使用Apache Commons Pool实现数据库连接池,apachecommons
使用Apache Commons Pool实现数据库连接池,apachecommons
官方示例参考:apache commons pool examples
通过组合Apache Commons Pool提供的GenericObjectPool实现数据库连接池
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import java.io.Closeable;
import java.sql.Connection;
public class DbPool implements Closeable {
private GenericObjectPool<Connection> internalPool;
public DbPool(GenericObjectPoolConfig poolConfig, PooledObjectFactory factory){
if (this.internalPool != null) {
try {
closeInternalPool();
} catch (Exception e) {
}
}
this.internalPool = new GenericObjectPool(factory, poolConfig);
}
// 获取连接
public Connection getConnection(){
Connection connection = null;
try {
connection = internalPool.borrowObject();
} catch (Exception e) {
throw new RuntimeException("Could not get connection from the pool", e);
}
return connection;
}
// 返还连接
public void returnConnection(Connection connection){
internalPool.returnObject(connection);
}
@Override
public void close(){
this.closeInternalPool();
}
private void closeInternalPool() {
try {
internalPool.close();
} catch (Exception e) {
throw new RuntimeException("Could not destroy the pool", e);
}
}
}
borrowObject的实现方式如下
public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
implements ObjectPool<T>, GenericObjectPoolMXBean, UsageTracking<T> {
private final PooledObjectFactory<T> factory;
private final LinkedBlockingDeque<PooledObject<T>> idleObjects;
public T borrowObject(final long borrowMaxWaitMillis) throws Exception {
......
p = idleObjects.pollFirst();
if (p == null) {
p = create();
if (p != null) {
create = true;
}
}
......
return p.getObject();
}
private PooledObject<T> create() throws Exception {
......
p = factory.makeObject();
......
return p;
}
}
对象池中并不直接保存最终使用的对象实例,而是使用PooledObject对最终使用的对象实例进行了一层封装
通过封装对象给对象实例增加了诸如状态、时间等一系列属性
DbConnectionFactory用来定义对象池中的对象实例的生命周期方法(创建、销毁等),通过继承Apache Commons Pool提供的BasePooledObjectFactory实现
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import java.sql.Connection;
import java.sql.DriverManager;
public class DbConnectionFactory extends BasePooledObjectFactory<Connection> {
private DbConfig dbConfig;
public DbConnectionFactory(DbConfig dbConfig){
super();
this.dbConfig = dbConfig;
}
// 创建新的数据库连接
public Connection create() throws Exception {
Connection connection = DriverManager.getConnection(dbConfig.getUrl(),
dbConfig.getUsername(), dbConfig.getPassword());
return connection;
}
// 使用PooledObject对数据库连接进行包装
public PooledObject<Connection> wrap(Connection connection) {
return new DefaultPooledObject(connection);
}
// 由于validateObject失败或其它什么原因,对象实例从对象池中移除时调用
// 不能保证对象实例被移除时所处的状态
public void destroyObject(PooledObject<Connection> pooledConnection) throws Exception {
Connection connection = pooledConnection.getObject();
connection.close();
}
// 仅能被active状态的对象实例调用
// 从对象池获取对象实例,在对象池返回该对象实例前,调用该方法校验其状态
// 对象实例归还给对象池时,在调用passivateObject方法前,使用该方法校验其状态
public boolean validateObject(PooledObject<Connection> pooledConnection) {
Connection connection = pooledConnection.getObject();
try {
if (connection.isValid(1))
return true;
else
return false;
}catch(Exception e){
return false;
}
}
// 对象实例在归还给对象池时调用了passivateObject方法,通过对象池再次取到该对象实例
// 在对象池返回该对象实例前,需要调用该方法
public void activateObject(PooledObject<Connection> pooledConnection) throws Exception {
}
// 对象实例归还给对象池时调用
public void passivateObject(PooledObject<Connection> pooledConnection) throws Exception {
}
}
DbConfig用来保存数据库配置
public class DbConfig {
private String url;
private String username;
private String password;
public DbConfig(String driver, String url, String username,
String password){
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
this.url = url;
this.username = username;
this.password = password;
}
public String getUrl() {
return url;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
}
DbPoolConfig用来保存对象池配置,通过继承Apache Commons Pool提供的GenericObjectPoolConfig实现
提供了很多对象池相关的配置属性以供使用
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
public class DbPoolConfig extends GenericObjectPoolConfig {
public DbPoolConfig(){
setMaxTotal(10);
setMaxIdle(5);
setMinIdle(2);
}
}
测试代码如下
import java.sql.Connection;
import java.sql.Statement;
public class Test {
public static void main(String[] args) throws Exception {
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://192.168.137.128:3306/mydb";
String username = "root";
String password = "";
DbConfig dbConnectionConfig = new DbConfig(
driver, url, username, password);
DbConnectionFactory dbConnectionFactory = new DbConnectionFactory(dbConnectionConfig);
DbPoolConfig dbPoolConfig = new DbPoolConfig();
dbPoolConfig.setMaxTotal(10);
dbPoolConfig.setMaxIdle(5);
dbPoolConfig.setMinIdle(2);
dbPoolConfig.setMaxWaitMillis(200);
dbPoolConfig.setTestOnBorrow(false);
dbPoolConfig.setTestOnReturn(false);
DbPool dbPool = new DbPool(dbPoolConfig, dbConnectionFactory);
for(int i = 0 ; i < 20 ; i++){
Connection connection = dbPool.getConnection();
Statement statement = connection.createStatement();
statement.execute("insert into t_person(name, age) values ('a', 20)");
dbPool.returnConnection(connection);
}
}
}
评论暂时关闭