记账本开发记录——第十天(2020.1.28)

今天,简单学习了JDBC连接池的概念和自定义连接池。

所谓连接池,就是连接完后不close,而是归还到连接池内,可以解决数据库连接的性能问题。

对于自定义连接池,我们可以自己创建连接池,然后通过这个连接池进行连接。如下代码:

 1 public class MyDataSource implements DataSource{
 2     // 创建一个List集合用于存放多个连接对象.
 3     private List<Connection> list = new ArrayList<Connection>();
 4     // 在程序开始的时候,初始化几个连接,将连接存放到list中.
 5     public MyDataSource() {
 6         // 初始化3个连接:
 7         for(int i=1;i<=3;i++){
 8             Connection conn = JDBCUtils.getConnection();
 9             list.add(conn);
10         }
11     }
12     
13     @Override
14     // 获得连接的方法:
15     public Connection getConnection() throws SQLException {
16         if(list.size() <= 0){
17             for(int i=1;i<=3;i++){
18                 Connection conn = JDBCUtils.getConnection();
19                 list.add(conn);
20             }    
21         }
22         Connection conn = list.remove(0);
23         return conn;
24     }
25     
26     // 归还连接的方法:
27     public void addBack(Connection conn){
28         list.add(conn);
29     }
30 ...
31 }

可这样的自定义连接会出现一定的问题,比如需要记住自己定义的API名字,并且不能使用面向对象的接口方式,等于是放弃了一个大好的特性。因此要解决这个问题,我们直接不定义自己的API,通过改写自带的方法,就可以达到一样的效果:

 1 public class MyConnection implements Connection{
 2  
 3     private Connection conn;
 4     private List<Connection> list;
 5  
 6     public MyConnection(Connection conn,List<Connection> list) {
 7         this.conn = conn;
 8         this.list = list;
 9     }
10  
11  
12     @Override
13     public void close() throws SQLException {
14         list.add(conn);
15     }
16      ...
17 }
18  
19 连接池的getConnection方法:
20     @Override
21     // 获得连接的方法:
22     public Connection getConnection() throws SQLException {
23         if(list.size() <= 0){
24             for(int i=1;i<=3;i++){
25                 Connection conn = JDBCUtils.getConnection();
26                 list.add(conn);
27             }    
28         }
29         Connection conn = list.remove(0);
30         MyConnection myConn = new MyConnection(conn, list);
31         return myConn;
32     }

但实际开发中,我们可以使用开源的连接池,如DBCP和C3P0,并且学习了这两个开源连接池的使用方式:

C3P0:

第一步:引入C3P0连接池的jar包.
第二步:编写代码:
* 手动设置参数:
* 配置文件设置参数:
 

我们也可以通过书写工具类来进行一个更为便捷的操作:

 1 public class JDBCUtils2 {
 2     private static final ComboPooledDataSource DATA_SOURCE =new ComboPooledDataSource();
 3     /**
 4      * 获得连接的方法
 5      */
 6     public static Connection getConnection(){
 7         Connection conn = null;
 8         try {
 9             conn = DATA_SOURCE.getConnection();
10         } catch (SQLException e) {
11             // TODO Auto-generated catch block
12             e.printStackTrace();
13         }
14         return conn;
15     }
16 ...

对于DBCP,配置要更为繁琐:

 1 @Test
 2     /**
 3      * 手动方式:
 4      */
 5     public void demo1(){
 6         Connection conn = null;
 7         PreparedStatement stmt = null;
 8         ResultSet rs = null;
 9         BasicDataSource dataSource = new BasicDataSource();
10         dataSource.setDriverClassName("com.mysql.jdbc.Driver");
11         dataSource.setUrl("jdbc:mysql:///web_07");
12         dataSource.setUsername("root");
13         dataSource.setPassword("123");
14         try{
15             // 获得连接:
16             conn = dataSource.getConnection();
17             // 编写SQL:
18             String sql = "select * from category";
19             // 预编译SQL:
20             stmt = conn.prepareStatement(sql);
21             // 执行SQL:
22             rs = stmt.executeQuery();
23             while(rs.next()){
24                 System.out.println(rs.getInt("cid")+"   "+rs.getString("cname"));
25             }
26         }catch(Exception e){
27             e.printStackTrace();
28         }finally{
29             JDBCUtils.release(rs,stmt, conn);
30         }
31     }
32     
33     @Test
34     /**
35      * 配置文件方式:
36      */
37     public void demo2(){
38         Connection conn = null;
39         PreparedStatement stmt = null;
40         ResultSet rs = null;
41         Properties properties = new Properties();
42         
43         try{
44             properties.load(new FileInputStream("src/dbcpconfig.properties"));
45             DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);
46             // 获得连接:
47             conn = dataSource.getConnection();
48             // 编写SQL:
49             String sql = "select * from category";
50             // 预编译SQL:
51             stmt = conn.prepareStatement(sql);
52             // 执行SQL:
53             rs = stmt.executeQuery();
54             while(rs.next()){
55                 System.out.println(rs.getInt("cid")+"   "+rs.getString("cname"));
56             }
57         }catch(Exception e){
58             e.printStackTrace();
59         }finally{
60             JDBCUtils.release(rs,stmt, conn);
61         }
62     }

目前来说,C3P0使用的xml配置文件要更为简单和方便。

之后,学习了DBUtils的使用。DBUtils就是把JDBC的各种操作进行了简化,下面是一些实例操作:

 1 package cn.itheima.jdbc.test;
 2 
 3 import java.sql.SQLException;
 4 
 5 import org.apache.commons.dbutils.QueryRunner;
 6 import org.junit.Test;
 7 
 8 import cn.itheima.jdbc.utils.C3P0Utils;
 9 
10 /**
11  * 测试DBUtils工具类的增删改操作
12  * 
13  * @author Never Say Never
14  * @date 2016年7月31日
15  * @version V1.0
16  */
17 public class TestDBUtils1 {
18 
19     /**
20      * 添加所有用户方法
21      */
22     @Test
23     public void testAddUser() {
24         try {
25             // 1.创建核心类QueryRunner
26             QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
27             // 2.编写SQL语句
28             String sql = "insert into tbl_user values(null,?,?)";
29             // 3.为站位符设置值
30             Object[] params = { "余淮", "耿耿" };
31             // 4.执行添加操作
32             int rows = qr.update(sql, params);
33             if (rows > 0) {
34                 System.out.println("添加成功!");
35             } else {
36                 System.out.println("添加失败!");
37             }
38         } catch (SQLException e) {
39             // TODO Auto-generated catch block
40             e.printStackTrace();
41         }
42     }
43     
44     /**
45      * 根据id修改用户方法
46      * 
47      */
48     @Test
49     public void testUpdateUserById() {
50         try {
51             // 1.创建核心类QueryRunner
52             QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
53             // 2.编写SQL语句
54             String sql = "update tbl_user set upassword=? where uid=?";
55             // 3.为站位符设置值
56             Object[] params = { "xxx", 21 };
57             // 4.执行添加操作
58             int rows = qr.update(sql, params);
59             if (rows > 0) {
60                 System.out.println("修改成功!");
61             } else {
62                 System.out.println("修改失败!");
63             }
64         } catch (SQLException e) {
65             // TODO Auto-generated catch block
66             e.printStackTrace();
67         }
68     }
69     
70     /**
71      * 根据id删除用户方法
72      */
73     @Test
74     public void testDeleteUserById() {
75         try {
76             // 1.创建核心类QueryRunner
77             QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
78             // 2.编写SQL语句
79             String sql = "delete from tbl_user where uid=?";
80             // 3.为站位符设置值
81             Object[] params = {19};
82             // 4.执行添加操作
83             int rows = qr.update(sql, params);
84             if (rows > 0) {
85                 System.out.println("删除成功!");
86             } else {
87                 System.out.println("删除失败!");
88             }
89         } catch (SQLException e) {
90             // TODO Auto-generated catch block
91             e.printStackTrace();
92         }
93     }
94 }
  1 package cn.itheima.jdbc.test;
  2 
  3 import java.sql.SQLException;
  4 import java.util.List;
  5 import java.util.Map;
  6 
  7 import org.apache.commons.dbutils.QueryRunner;
  8 import org.apache.commons.dbutils.handlers.BeanHandler;
  9 import org.apache.commons.dbutils.handlers.BeanListHandler;
 10 import org.apache.commons.dbutils.handlers.ColumnListHandler;
 11 import org.apache.commons.dbutils.handlers.MapListHandler;
 12 import org.apache.commons.dbutils.handlers.ScalarHandler;
 13 import org.junit.Test;
 14 
 15 import cn.itheima.domain.User;
 16 import cn.itheima.jdbc.utils.C3P0Utils;
 17 
 18 /**
 19  * 测试DBUtils查询操作
 20  * 
 21  * @author Never Say Never
 22  * @date 2016年7月31日
 23  * @version V1.0
 24  */
 25 public class TestDBUtils2 {
 26 
 27     /*
 28      * 查询所有用户方法
 29      */
 30     @Test
 31     public void testQueryAll() {
 32         try {
 33             // 1.获取核心类queryRunner
 34             QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
 35             // 2.编写sql语句
 36             String sql = "select * from tbl_user";
 37             // 3.执行查询操作
 38             List<User> users = qr.query(sql, new BeanListHandler<User>(User.class));
 39             // 4.对结果集集合进行遍历
 40             for (User user : users) {
 41                 System.out.println(user.getUname() + " : " + user.getUpassword());
 42             }
 43         } catch (SQLException e) {
 44             throw new RuntimeException(e);
 45         }
 46     }
 47     
 48     /*
 49      * 根据id查询用户方法
 50      */
 51     @Test
 52     public void testQueryUserById() {
 53         try {
 54             // 1.获取核心类queryRunner
 55             QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
 56             // 2.编写sql语句
 57             String sql = "select * from tbl_user where uid=?";
 58             //3.为占位符设置值
 59             Object[] params = {21};
 60             // 4.执行查询操作
 61             User user = qr.query(sql, new BeanHandler<User>(User.class), params);
 62             System.out.println(user.getUname() + " : " + user.getUpassword());
 63         } catch (SQLException e) {
 64             throw new RuntimeException(e);
 65         }
 66     }
 67     
 68     /*
 69      * 根据所有用户的总个数
 70      */
 71     @Test
 72     public void testQueryCount() {
 73         try {
 74             // 1.获取核心类queryRunner
 75             QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
 76             // 2.编写sql语句
 77             String sql = "select count(*) from tbl_user";
 78             // 4.执行查询操作
 79             Long count = (Long) qr.query(sql, new ScalarHandler());
 80             System.out.println(count);
 81         } catch (SQLException e) {
 82             throw new RuntimeException(e);
 83         }
 84     }
 85     
 86     /*
 87      * 查询所有用户方法
 88      */
 89     @Test
 90     public void testQueryAll1() {
 91         try {
 92             // 1.获取核心类queryRunner
 93             QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
 94             // 2.编写sql语句
 95             String sql = "select * from tbl_user";
 96             // 3.执行查询操作
 97             List<Map<String, Object>> list = qr.query(sql, new MapListHandler());
 98             // 4.对结果集集合进行遍历
 99             for (Map<String, Object> map : list) {
100                 System.out.println(map);
101             }
102         } catch (SQLException e) {
103             throw new RuntimeException(e);
104         }
105     }
106     
107     /*
108      * 查询所有用户方法
109      */
110     @Test
111     public void testQueryAll2() {
112         try {
113             // 1.获取核心类queryRunner
114             QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
115             // 2.编写sql语句
116             String sql = "select * from tbl_user";
117             // 3.执行查询操作
118             List<Object> list = qr.query(sql, new ColumnListHandler("uname"));
119             // 4.对结果集集合进行遍历
120             for (Object object : list) {
121                 System.out.println(object);
122             }
123         } catch (SQLException e) {
124             throw new RuntimeException(e);
125         }
126     }
127 }

需要注意的是,DBUtils的方法有一些涉及到map和list等集合,这部分需要好好进行理解。

今日学习的问题:有一些jar包虽然名字一样,但实际使用起来却不一样,需要仔细看看。

上一篇:dbutils介绍


下一篇:Node.js GET/POST请求