实现JDBC连接池

因为每次数据库连接的创建和销毁都比较耗时耗力。因此基本策略时候使用JDBC连接池来管理所有的连接。

一般connection pool 只是一个 LinkedList 即可。

比如我们自己写一个javax.sql.DataSource的实现类,类中有一个private变量: LinkedList<Connection> pool = new LinkedList<Connection>();

可以写一个静态代码快来初始化pool变量: 如新建10个Conncetion。

private static LinkedList<Connection> pool = new LinkedList<Connection>();
static{
//初始化DriverManager
//......
for(int i=0; i<10; i++){
   Connection conn = DriverManager.getConnection(url, username,password);
   pool.add(conn);
 }
}

 

当客户端调用dataSource.getConnection() 时并不新建Connection, 而是从pool中取出一个Connection实例传给客户端。

但是,当客户端调用connection.close(); 函数时, 我们应实现将次connection还回pool中,而不是真的关闭connection。但是connection.close() 函数本是被Driver实现的(mysql 的话是mysql的driver, oracle的话是oracle的driver。我们是无法改变driver内部的实现的。解决方案只能是外部对close() 方法的重写或扩展。

解决方案:

(一). 装饰模式

被改写类: com.mysql.jdbc.Connection

编写一个类CustomedConnection 实现与com.mysql.jdbc.Connection 相同的接口(java.sql.Conneciton)

public class CustomedConnection implements java.sql.Connection{
  private Connection sqlConnection ;
  private LinkedList<Connection> pool;

  public CustomedConnection(Connection sqlConnection, LinkedList<Connection> pool){
      this.sqlConnection = sqlConnection;
      this.pool = pool;
}

  public void close(){
    this.pool.add(sqlConnection);
}


 // ......
//java.sql.Connection 的其他方法的实现都直接调用sqlConnection的实现即可。除了close() 方法。
//  ......

}

 DataSource 的实现中:

public synchronized Connection getConnection() throws SQLException{
if(pool.size()>0){
    Connection conn = pool.remove();//从池中拿出一个connection
    CustomedConnection customedConnection = new CustomedConnection(conn, pool);
     return customedConnection;
}
else{
    throw new RuntimeException(“sorry, server busy”);
}
}

 

 (二). 适配器模式

   

public class ConnectionAdaptor implements Connection{
      private Connection conn;
      public ConnectionAdaptor(Connection conn){
              this.conn=conn;  
      }
     //重写所有Connection的方法:都直接调用conn的响应方法即可。
     //......
}

//接下来写一个CustomedConnection 继承此适配器:
public class CustomedConnection extends ConnectionAdaptor {
    private LinkedList<Connection> pool ;
    public CustomedConnection(Connection conn, LinkedList<Connection> pool){
       super(conn);
       this.pool = pool;
}

//重写close() 方法即可
//......

}

 (三).动态代理

    在实现DataSource的getConnection()方法里,拦截Connection的所有方法,如果方法名为close, 则改变其原本逻辑:

public synchronized Connection getConnection(){
  if(pool.size()>0){
  final Connection conn = pool.remove();
  return Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler(){
           @Override
           public Object invoke(Object proxy, Method method, Object[] args){
                    if("close".equals(methode))
                          return pool.add(conn);
                    else 
                          return method.invoke(proxy, args);
             }
      }
  );
}
}

 

你可能感兴趣的:(jdbc)