MySQL学习(六)——自定义连接池

1、连接池概念

用池来管理Connection,这样可以重复使用Connection。有了池,我们就不用自己来创建Connection,而是通过池来获取Connection对象。当使用完Connection后,调用Connection的close()方法也不会真的关闭Connection,而是把Connection“归还”给池,池就可以再利用这个Connection对象了。

2、自定义连接池

1)基于MySQL学习(五)——使用JDBC完成用户表CRUD的操作,把db.properties和JDBCUtils_V3.java文件复制到当前包下

2)MyConnection.java文件

装饰者设计模式,专门用于增强方法(此处如果不对close()做增强方法,用户调用conn.close()将连接真正释放,连接池将无连接可用,所以我们希望用户调用了close()方法,连接仍归还给连接池)

 1 //1.实现同一个接口
 2 public class MyConnection implements Connection{
 3     //3.定义变量
 4     private Connection conn;
 5     
 6     private LinkedList<Connection> pool;
 7     
 8     //2.编写一个构造方法(参数使用了面向对象的多态特性)
 9     public    MyConnection(Connection conn,LinkedList<Connection> pool){
10         this.conn=conn;
11         this.pool=pool;
12     }
13     //4.书写需要增强的方法
14     @Override
15     public void close() throws SQLException {
16         pool.add(conn);
17     }
18     /*
19      * 此方法必须覆盖!否则会出现空指针异常
20      */
21     @Override
22     public PreparedStatement prepareStatement(String sql) throws SQLException {
23         return conn.prepareStatement(sql);
24     }
25     ……
26 }

3)MyDataSource1.java文件

创建连接池实现数据源,并实现接口javax.sql.DataSource

 1 public class MyDataSource1 implements DataSource{
 2     //1.创建一个容器用于存储Connection对象
 3     private static LinkedList<Connection> pool=new LinkedList<Connection>();
 4     //2.创建5个连接放到容器中去
 5     static{
 6         for(int i=0;i<5;i++){
 7             Connection conn=JDBCUtils_V3.getConnection();
 8             //放入池子中的connection对象已经经过改造了
 9             MyConnection myconn=new MyConnection(conn,pool);
10             pool.add(myconn);
11         }
12     }
13     /**
14      * 重写获取连接的方法
15      */
16     @Override
17     public Connection getConnection() throws SQLException {
18         Connection conn=null;
19         //3.使用前先判断
20         if(pool.size()==0){
21             //3.1池子里没有,我们再创建一些
22             conn=JDBCUtils_V3.getConnection();
23             pool.add(conn);
24         }
25         //4.从池子里面获取一个连接对象Connection
26         conn=pool.remove(0); 
27         return conn;
28     }
29     ……
30 }

4)TestMyDataSource.java文件

 1 public class TestMyDataSource {
 2     /*
 3      * 添加用户
 4      * 使用改造过后的Connection
 5      */ 
 6     @Test
 7     public void testAddUser1(){
 8         Connection conn=null;
 9         PreparedStatement pstmt=null;
10         //1.创建自定义连接池对象
11         DataSource dataSource=new MyDataSource1();
12         
13         try {
14             //2.从池子中获取连接
15             conn=dataSource.getConnection();
16             String sql="insert tbl_user values(null,?,?)";
17             //必须在自定义的conntection类中重写prepareStatement(sql)语句
18             pstmt=conn.prepareStatement(sql);
19             pstmt.setString(1, "chenga");
20             pstmt.setString(2, "123");
21             int rows=pstmt.executeUpdate();
22             if(rows>0){
23                 System.out.println("添加成功");
24             }else{
25                 System.out.println("添加不成功");
26             }
27         } catch (SQLException e) {
28             e.printStackTrace();
29         }finally{
30             //调用的release()方法中的close()其实是MyConnection的close()方法,该方法内部将当前连接归还到连接池
31             JDBCUtils_V3.release(conn,pstmt,null);         
32         }
33     }
34 }

执行Junit Test,效果如下:

原文地址:https://www.cnblogs.com/cxq1126/p/7501210.html