Java爲連接池實現提供了一個規範(接口),規範的寫法,我們需要實現DataSource接口!
1.定義數據庫的資源連接池 MyDbPool
package com.scc.utils;
import javax.sql.DataSource;
import java.io.InputStream;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;
/**
* scc
*/
public class MyDbPool implements DataSource {
private static String driverClass = null;
private static String url = null;
private static String user = null;
private static String password = null;
private static List<Connection> connections;
static {
connections= Collections.synchronizedList(new ArrayList<>());
try {
//加載屬性文件
InputStream is = MyDbPool.class.getClassLoader().getResourceAsStream("db.properties");
//創建一個集合
Properties properties = new Properties();
//從流中加載
properties.load(is);
//獲取相應的屬性值
driverClass = properties.getProperty("driverClass");
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
System.out.println(driverClass+" "+url+"..."+user+"..."+password);
//註冊驅動
Class.forName(driverClass);
for (int i = 0; i < 20; i++) {
connections.add(DriverManager.getConnection(url, user, password));
}
System.out.println("數據庫連接池初始化完成");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Connection getConnection() throws SQLException {
synchronized (connections){
if(connections.size()>0){
Connection connection = connections.remove(0);
System.out.println("使用了:"+connection.toString());
return connection;
}
}
return null;
}
//釋放資源
public static void release(Connection conn){
System.out.println("歸還了:"+conn.toString());
connections.add(conn);
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
}
2.封裝DButils工具類
package com.scc.utils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
* scc
* 1.註冊驅動
* 2.獲取連接
* 3.釋放資源
* 4.執行增刪改
* 5.查
*/
public class DBUtils {
private static MyDbPool mypool;
//註冊
static {
mypool=new MyDbPool();
}
//數據庫連接
public static Connection getConnection() {
try {
return mypool.getConnection();
} catch (SQLException e) {
e.printStackTrace();
System.out.println("連接失敗");
}
return null;
}
//關流
public static void closeAll(PreparedStatement pstat, Connection conn, ResultSet res) {
try {
if (res != null) {
res.close();
}
if (pstat != null) {
pstat.close();
}
if (conn != null) {
mypool.release(conn);//歸還連接
}
} catch (SQLException e) {
e.printStackTrace();
System.out.println("沒有開流,不用關");
}
}
//增刪改操作
public static int executeUpdate(String sql, Object[] params) {
Connection conn = null;
PreparedStatement pstat = null;
if (sql != null) {
try {
//獲取連接
conn = getConnection();
//創建命令
pstat = conn.prepareStatement(sql);
//遍歷參數並賦值
if (params != null) {
for (int i = 0; i < params.length; i++) {
pstat.setObject(i + 1, params[i]);
}
}
//執行方法
return pstat.executeUpdate(); //返回值爲int類型
} catch (SQLException e) {
e.printStackTrace();
} finally {
closeAll(pstat, conn, null);
}
}
return -1;
}
//獲取單條數據 參數可以變化
public static <T> T findSingle(String sql, Object[] params, Class<T> clazz) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = getConnection();
ps = conn.prepareStatement(sql);
if (params != null) {
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1, params[i]);
}
}
rs = ps.executeQuery();
T obj = clazz.newInstance();//創建實體類的實例對象
if (rs.next()) {
ResultSetMetaData metaData = rs.getMetaData();//獲取ResultSet的返回值對象的元數據集合
System.out.println("列數:" + metaData.getColumnCount());
for (int i = 0; i < metaData.getColumnCount(); i++) {
String columnName = metaData.getColumnName(i + 1);
PropertyDescriptor pd = new PropertyDescriptor(columnName, clazz);//返回的是一個對象
System.out.println("PropertyDescriptor的對象,pd:" + pd);
if (pd != null) {
Method writeMethod = pd.getWriteMethod();
writeMethod.invoke(obj, rs.getObject(columnName));
}
}
}
return obj;
} catch (Exception e) {
e.printStackTrace();
System.out.println("查詢異常");
} finally {
closeAll(ps, conn, rs);
}
return null;
}
//查找 多條數據
public static <T> List<T> findAll(String sql, Object[] params, Class<T> clazz) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<T> list = new ArrayList<>();
try {
conn = getConnection();
ps = conn.prepareStatement(sql);
if (params != null) {
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1, params[i]);
}
}
rs = ps.executeQuery();
// T obj = clazz.newInstance();//這句話不能放在外面,因爲要把對象的地址放到list集合裏,集合裏的所有數據都單獨對應一個地址
ResultSetMetaData metaData = rs.getMetaData();//這個是獲取SQL語句中要查詢的列名對象,放在while裏面和外賣都行
while (rs.next()) {
T obj = clazz.newInstance();//沒創建一個對象,就把相應的地址引用方法list集合裏
for (int i = 0; i < metaData.getColumnCount(); i++) {
String columnName = metaData.getColumnName(i + 1);
Object value = rs.getObject(columnName);
PropertyDescriptor pd = new PropertyDescriptor(columnName, clazz);
Method writeMethod = pd.getWriteMethod();
writeMethod.invoke(obj, value);
}
list.add(obj);
}
return list;
} catch (Exception e) {
e.printStackTrace();
System.out.println("查詢異常");
} finally {
closeAll(ps, conn, rs);
}
return null;
}
}
3.測試類
package com.scc.demo;
import com.scc.utils.DBUtils;
import java.sql.Connection;
/**
* scc
*/
public class PoolTest {
public static void main(String[] args) {
for (int i = 0; i < 20; i++) {
Connection conn = DBUtils.getConnection();
System.out.println("獲取連接:"+conn.toString());
DBUtils.closeAll(null, conn, null);
}
}
}
運行結果
"C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2018.3.3\lib\idea_rt.jar=65478:D:\Program Files\JetBrains\IntelliJ IDEA 2018.3.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;E:\IdeaWorkplace\JDBC2\out\production\JDBC2;E:\IdeaWorkplace\JDBC2\lib\mysql-connector-java-5.1.41-bin.jar;E:\Software02\repository\junit\junit\4.12\junit-4.12.jar;E:\Software02\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.scc.demo.PoolTest
com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/student...root...123456
數據庫連接池初始化完成
使用了:com.mysql.jdbc.JDBC4Connection@4ccabbaa
獲取連接:com.mysql.jdbc.JDBC4Connection@4ccabbaa
歸還了:com.mysql.jdbc.JDBC4Connection@4ccabbaa
使用了:com.mysql.jdbc.JDBC4Connection@4bf558aa
獲取連接:com.mysql.jdbc.JDBC4Connection@4bf558aa
歸還了:com.mysql.jdbc.JDBC4Connection@4bf558aa
使用了:com.mysql.jdbc.JDBC4Connection@2d38eb89
獲取連接:com.mysql.jdbc.JDBC4Connection@2d38eb89
歸還了:com.mysql.jdbc.JDBC4Connection@2d38eb89
使用了:com.mysql.jdbc.JDBC4Connection@5fa7e7ff
獲取連接:com.mysql.jdbc.JDBC4Connection@5fa7e7ff
歸還了:com.mysql.jdbc.JDBC4Connection@5fa7e7ff
使用了:com.mysql.jdbc.JDBC4Connection@4629104a
獲取連接:com.mysql.jdbc.JDBC4Connection@4629104a
歸還了:com.mysql.jdbc.JDBC4Connection@4629104a
使用了:com.mysql.jdbc.JDBC4Connection@27f8302d
獲取連接:com.mysql.jdbc.JDBC4Connection@27f8302d
歸還了:com.mysql.jdbc.JDBC4Connection@27f8302d
使用了:com.mysql.jdbc.JDBC4Connection@4d76f3f8
獲取連接:com.mysql.jdbc.JDBC4Connection@4d76f3f8
歸還了:com.mysql.jdbc.JDBC4Connection@4d76f3f8
使用了:com.mysql.jdbc.JDBC4Connection@2d8e6db6
獲取連接:com.mysql.jdbc.JDBC4Connection@2d8e6db6
歸還了:com.mysql.jdbc.JDBC4Connection@2d8e6db6
使用了:com.mysql.jdbc.JDBC4Connection@23ab930d
獲取連接:com.mysql.jdbc.JDBC4Connection@23ab930d
歸還了:com.mysql.jdbc.JDBC4Connection@23ab930d
使用了:com.mysql.jdbc.JDBC4Connection@4534b60d
獲取連接:com.mysql.jdbc.JDBC4Connection@4534b60d
歸還了:com.mysql.jdbc.JDBC4Connection@4534b60d
使用了:com.mysql.jdbc.JDBC4Connection@3fa77460
獲取連接:com.mysql.jdbc.JDBC4Connection@3fa77460
歸還了:com.mysql.jdbc.JDBC4Connection@3fa77460
使用了:com.mysql.jdbc.JDBC4Connection@619a5dff
獲取連接:com.mysql.jdbc.JDBC4Connection@619a5dff
歸還了:com.mysql.jdbc.JDBC4Connection@619a5dff
使用了:com.mysql.jdbc.JDBC4Connection@1ed6993a
獲取連接:com.mysql.jdbc.JDBC4Connection@1ed6993a
歸還了:com.mysql.jdbc.JDBC4Connection@1ed6993a
使用了:com.mysql.jdbc.JDBC4Connection@7e32c033
獲取連接:com.mysql.jdbc.JDBC4Connection@7e32c033
歸還了:com.mysql.jdbc.JDBC4Connection@7e32c033
使用了:com.mysql.jdbc.JDBC4Connection@7ab2bfe1
獲取連接:com.mysql.jdbc.JDBC4Connection@7ab2bfe1
歸還了:com.mysql.jdbc.JDBC4Connection@7ab2bfe1
使用了:com.mysql.jdbc.JDBC4Connection@497470ed
獲取連接:com.mysql.jdbc.JDBC4Connection@497470ed
歸還了:com.mysql.jdbc.JDBC4Connection@497470ed
使用了:com.mysql.jdbc.JDBC4Connection@63c12fb0
獲取連接:com.mysql.jdbc.JDBC4Connection@63c12fb0
歸還了:com.mysql.jdbc.JDBC4Connection@63c12fb0
使用了:com.mysql.jdbc.JDBC4Connection@b1a58a3
獲取連接:com.mysql.jdbc.JDBC4Connection@b1a58a3
歸還了:com.mysql.jdbc.JDBC4Connection@b1a58a3
使用了:com.mysql.jdbc.JDBC4Connection@6438a396
獲取連接:com.mysql.jdbc.JDBC4Connection@6438a396
歸還了:com.mysql.jdbc.JDBC4Connection@6438a396
使用了:com.mysql.jdbc.JDBC4Connection@e2144e4
獲取連接:com.mysql.jdbc.JDBC4Connection@e2144e4
歸還了:com.mysql.jdbc.JDBC4Connection@e2144e4
Process finished with exit code 0