• 记账本开发记录——第十天(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包虽然名字一样,但实际使用起来却不一样,需要仔细看看。

  • 相关阅读:
    【[SDOI2014]旅行】
    【[USACO16OPEN]262144】
    【[SDOi2012]Longge的问题】
    【[POI2000]病毒】
    【不同子串个数】
    【工艺】
    Lambda使用深入解析
    Lambda表达式语法进一步巩固
    给之前绘制的图形菜单增加随触摸360度旋转效果
    给之前绘制的饼状图增加点击扩大突出效果
  • 原文地址:https://www.cnblogs.com/wushenjiang/p/12238579.html
Copyright © 2020-2023  润新知