创建一个工具类: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