創建一個工具類:JDBCUtils
package com.example.demo.Util;
import lombok.extern.slf4j.Slf4j;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;
import java.util.Queue;
/**
* @ClassName: JDBCUtils
* @Description: 實現連接池效果,初始化10個JDBC連接對象並放入池中,提供方法每次返回一個對象
* @Author: xuezhouyi
* @Version: V1.0
**/
@Slf4j
public class JDBCUtils {
private static String driver;
private static String url;
private static String username;
private static String password;
//連接池
private static Queue<Connection> pool = new LinkedList<>();
static {
Properties properties = new Properties();
InputStream is = null;
try {
is = JDBCUtils.class.getClassLoader().getResourceAsStream("mysql.properties");
properties.load(is);
driver = properties.getProperty("mysql.driver");
url = properties.getProperty("mysql.url");
username = properties.getProperty("mysql.username");
password = properties.getProperty("mysql.password");
} catch (Exception e) {
e.printStackTrace();
}
//創建三個連接對象(包裝類對象)放到池子中
for (int i = 0; i < 10; i++) {
Connection connection;
try {
Class.forName(driver);
connection = DriverManager.getConnection(url, username, password);
Connection connectionWrapper = new ConnectionWrapper(connection, pool);
pool.add(connectionWrapper);
} catch (Exception e) {
e.printStackTrace();
}
log.info("第" + i + "個連接對象放入池中");
}
}
//返回連接對象
public static Connection getConnection() {
Connection connection = null;
if (pool.size() > 0) {
connection = pool.poll();
} else {
//等待超時,返回一個新創建的對象
try {
connection = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
e.printStackTrace();
}
}
log.info("取出一個對象後,當前池子中有" + pool.size() + "個對象");
return connection;
}
}
實現Connection接口修改close方法
package com.example.demo.Util;
import lombok.extern.slf4j.Slf4j;
import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.Map;
import java.util.Properties;
import java.util.Queue;
import java.util.concurrent.Executor;
/**
* @ClassName: ConnectionWrapper
* @Description: 實現一個Connection接口重寫close方法將對象歸還池中
* @Author: xuezhouyi
* @Version: V1.0
**/
@Slf4j
public class ConnectionWrapper implements Connection {
private Connection connection;
private Queue<Connection> pool;
public ConnectionWrapper(Connection connection, Queue<Connection> pool) {
this.connection = connection;
this.pool = pool;
}
@Override
public Statement createStatement() throws SQLException {
return null;
}
//傳入SQL
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
PreparedStatement prepareStatement = connection.prepareStatement(sql);
return prepareStatement;
}
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
return null;
}
@Override
public String nativeSQL(String sql) throws SQLException {
return null;
}
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
}
@Override
public boolean getAutoCommit() throws SQLException {
return false;
}
@Override
public void commit() throws SQLException {
}
@Override
public void rollback() throws SQLException {
}
//歸還
@Override
public void close() throws SQLException {
pool.offer(this);
log.info("歸還一個連接對象後,當前池中還剩" + pool.size() + "個對象");
}
@Override
public boolean isClosed() throws SQLException {
return false;
}
@Override
public DatabaseMetaData getMetaData() throws SQLException {
return null;
}
@Override
public void setReadOnly(boolean readOnly) throws SQLException {
}
@Override
public boolean isReadOnly() throws SQLException {
return false;
}
@Override
public void setCatalog(String catalog) throws SQLException {
}
@Override
public String getCatalog() throws SQLException {
return null;
}
@Override
public void setTransactionIsolation(int level) throws SQLException {
}
@Override
public int getTransactionIsolation() throws SQLException {
return 0;
}
@Override
public SQLWarning getWarnings() throws SQLException {
return null;
}
@Override
public void clearWarnings() throws SQLException {
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return null;
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return null;
}
@Override
public Map<String, Class<?>> getTypeMap() throws SQLException {
return null;
}
@Override
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
}
@Override
public void setHoldability(int holdability) throws SQLException {
}
@Override
public int getHoldability() throws SQLException {
return 0;
}
@Override
public Savepoint setSavepoint() throws SQLException {
return null;
}
@Override
public Savepoint setSavepoint(String name) throws SQLException {
return null;
}
@Override
public void rollback(Savepoint savepoint) throws SQLException {
}
@Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
return null;
}
@Override
public Clob createClob() throws SQLException {
return null;
}
@Override
public Blob createBlob() throws SQLException {
return null;
}
@Override
public NClob createNClob() throws SQLException {
return null;
}
@Override
public SQLXML createSQLXML() throws SQLException {
return null;
}
@Override
public boolean isValid(int timeout) throws SQLException {
return false;
}
@Override
public void setClientInfo(String name, String value) throws SQLClientInfoException {
}
@Override
public void setClientInfo(Properties properties) throws SQLClientInfoException {
}
@Override
public String getClientInfo(String name) throws SQLException {
return null;
}
@Override
public Properties getClientInfo() throws SQLException {
return null;
}
@Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
return null;
}
@Override
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
return null;
}
@Override
public void setSchema(String schema) throws SQLException {
}
@Override
public String getSchema() throws SQLException {
return null;
}
@Override
public void abort(Executor executor) throws SQLException {
}
@Override
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
}
@Override
public int getNetworkTimeout() throws SQLException {
return 0;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
}
測試類
package com.example.demo;
import com.example.demo.Util.JDBCUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class DemoApplicationTests {
@Test
public void contextLoads() throws SQLException {
final Connection connection = JDBCUtils.getConnection();
final PreparedStatement pstm = connection.prepareStatement("select * from db");
final ResultSet resultSet = pstm.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getString("db")+"-"+resultSet.getString("user"));
}
final Connection connection1 = JDBCUtils.getConnection();
final Connection connection2 = JDBCUtils.getConnection();
connection.close();
connection1.close();
connection2.close();
}
}
測試日誌
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.1.RELEASE)
2019-11-24 20:18:55.617 INFO 4244 --- [ main] com.example.demo.DemoApplicationTests : Starting DemoApplicationTests on XavierXue with PID 4244 (started by XavierXue in C:\Users\XavierXue\IdeaProjects\apache\demo)
2019-11-24 20:18:55.619 INFO 4244 --- [ main] com.example.demo.DemoApplicationTests : No active profile set, falling back to default profiles: default
2019-11-24 20:18:56.368 INFO 4244 --- [ main] com.example.demo.DemoApplicationTests : Started DemoApplicationTests in 1.283 seconds (JVM running for 2.649)
2019-11-24 20:18:56.929 INFO 4244 --- [ main] com.example.demo.Util.JDBCUtils : 第0個連接對象放入池中
2019-11-24 20:18:56.934 INFO 4244 --- [ main] com.example.demo.Util.JDBCUtils : 第1個連接對象放入池中
2019-11-24 20:18:56.938 INFO 4244 --- [ main] com.example.demo.Util.JDBCUtils : 第2個連接對象放入池中
2019-11-24 20:18:56.942 INFO 4244 --- [ main] com.example.demo.Util.JDBCUtils : 第3個連接對象放入池中
2019-11-24 20:18:56.946 INFO 4244 --- [ main] com.example.demo.Util.JDBCUtils : 第4個連接對象放入池中
2019-11-24 20:18:56.951 INFO 4244 --- [ main] com.example.demo.Util.JDBCUtils : 第5個連接對象放入池中
2019-11-24 20:18:56.955 INFO 4244 --- [ main] com.example.demo.Util.JDBCUtils : 第6個連接對象放入池中
2019-11-24 20:18:56.960 INFO 4244 --- [ main] com.example.demo.Util.JDBCUtils : 第7個連接對象放入池中
2019-11-24 20:18:56.963 INFO 4244 --- [ main] com.example.demo.Util.JDBCUtils : 第8個連接對象放入池中
2019-11-24 20:18:56.967 INFO 4244 --- [ main] com.example.demo.Util.JDBCUtils : 第9個連接對象放入池中
2019-11-24 20:18:56.968 INFO 4244 --- [ main] com.example.demo.Util.JDBCUtils : 取出一個對象後,當前池子中有9個對象
sys-mysql.sys
2019-11-24 20:18:56.982 INFO 4244 --- [ main] com.example.demo.Util.JDBCUtils : 取出一個對象後,當前池子中有8個對象
2019-11-24 20:18:56.982 INFO 4244 --- [ main] com.example.demo.Util.JDBCUtils : 取出一個對象後,當前池子中有7個對象
2019-11-24 20:18:56.982 INFO 4244 --- [ main] com.example.demo.Util.ConnectionWrapper : 歸還一個連接對象後,當前池中還剩8個對象
2019-11-24 20:18:56.982 INFO 4244 --- [ main] com.example.demo.Util.ConnectionWrapper : 歸還一個連接對象後,當前池中還剩9個對象
2019-11-24 20:18:56.982 INFO 4244 --- [ main] com.example.demo.Util.ConnectionWrapper : 歸還一個連接對象後,當前池中還剩10個對象
Process finished with exit code 0