jdbc连接池

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

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

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

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

Java代码   收藏代码
  1. private static LinkedList<Connection> pool = new LinkedList<Connection>();  
  2. static{  
  3. //初始化DriverManager  
  4. //......  
  5. for(int i=0; i<10; i++){  
  6.    Connection conn = DriverManager.getConnection(url, username,password);  
  7.    pool.add(conn);  
  8.  }  
  9. }  

 

当客户端调用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)

Java代码   收藏代码
  1. public class CustomedConnection implements java.sql.Connection{  
  2.   private Connection sqlConnection ;  
  3.   private LinkedList<Connection> pool;  
  4.   
  5.   public CustomedConnection(Connection sqlConnection, LinkedList<Connection> pool){  
  6.       this.sqlConnection = sqlConnection;  
  7.       this.pool = pool;  
  8. }  
  9.   
  10.   public void close(){  
  11.     this.pool.add(sqlConnection);  
  12. }  
  13.   
  14.   
  15.  // ......  
  16. //java.sql.Connection 的其他方法的实现都直接调用sqlConnection的实现即可。除了close() 方法。  
  17. //  ......  
  18.   
  19. }  

 DataSource 的实现中:

Java代码   收藏代码
  1. public synchronized Connection getConnection() throws SQLException{  
  2. if(pool.size()>0){  
  3.     Connection conn = pool.remove();//从池中拿出一个connection  
  4.     CustomedConnection customedConnection = new CustomedConnection(conn, pool);  
  5.      return customedConnection;  
  6. }  
  7. else{  
  8.     throw new RuntimeException(“sorry, server busy”);  
  9. }  
  10. }  

 

 (二). 适配器模式

   

Java代码   收藏代码
  1. public class ConnectionAdaptor implements Connection{  
  2.       private Connection conn;  
  3.       public ConnectionAdaptor(Connection conn){  
  4.               this.conn=conn;    
  5.       }  
  6.      //重写所有Connection的方法:都直接调用conn的响应方法即可。  
  7.      //......  
  8. }  
  9.   
  10. //接下来写一个CustomedConnection 继承此适配器:  
  11. public class CustomedConnection extends ConnectionAdaptor {  
  12.     private LinkedList<Connection> pool ;  
  13.     public CustomedConnection(Connection conn, LinkedList<Connection> pool){  
  14.        super(conn);  
  15.        this.pool = pool;  
  16. }  
  17.   
  18. //重写close() 方法即可  
  19. //......  
  20.   
  21. }  

 (三).动态代理

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

Java代码   收藏代码
  1. public synchronized Connection getConnection(){  
  2.   if(pool.size()>0){  
  3.   final Connection conn = pool.remove();  
  4.   return Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler(){  
  5.            @Override  
  6.            public Object invoke(Object proxy, Method method, Object[] args){  
  7.                     if("close".equals(methode))  
  8.                           return pool.add(conn);  
  9.                     else   
  10.                           return method.invoke(proxy, args);  
  11.              }  
  12.       }  
  13.   );  
  14. }  
  15. }  

 

猜你喜欢

转载自arual.iteye.com/blog/2216043