jdbc连接池,dbUtils


连接池:

一、什么是连接池:
    1. JDBC访问数据库的步骤:
        1) 创建连接 --> 2) 访问数据库 --> 3) 关闭连接
  
    2. 使用连接池解决
        1) 由服务器在启动的时候,就创建好一定数据的连接对象。
        2) 用户从创建好的连接池中,直接取出一个连接对象即可
        3) 如果一个连接对象使用完毕,则将连接对象放回到连接池中。

 

二、数据库连接池API:

    1. 数据源接口
        javax.sql.DataSource 数据源(连接池),所有的连接池都必须要实现这个接口。
       
    2. 得到连接的方法:
        Connection getConnection() 不指定参数,得到一个连接对象
   
    3. 连接池常用的初始参数:(所有的连接池都有默认参数)
        1) 初始连接数,连接池创建的时候,创建的连接对象
        2) 最大连接数,连接池中连接数上限。
        3) 最大等待时间,如果超时,抛出异常。如果连接池中没有连接对象,等待多久。
        4) 最大空闲等待时间,如果一个用户得到了连接对象,多久没有发送SQL语句,就会被连接池回收。

 

C3P0连接池:

        1) 开放源代码,免费使用
        2) Hibernate框架(访问数据库)中默认使用的连接池

    1. 使用步骤:

        1) 导包 c3p0-0.9.5.2.jar  、mchange-commons-java-0.2.12.jar
        2) 设置参数(通过源代码或通过配置文件)
            要设置两类参数:
            2.1) 数据库连接参数(用户名,密码,URL,驱动)
            2.2) 数据库连接池的参数
        3) 得到连接池(数据源)
        4) 从连接池中得到连接对象

  1     public static void main(String[] args) throws Exception {
  2         // 1.创建数据源对象
  3         ComboPooledDataSource ds = new ComboPooledDataSource();
  4         // 2. 设置数据库的连接参数
  5         // 用户名,密码,URL,驱动
  6         ds.setUser("root");
  7         ds.setPassword("root");
  8         ds.setJdbcUrl("jdbc:mysql://localhost:3306/day25");
  9         ds.setDriverClass("com.mysql.jdbc.Driver");
 10         // 3. 设置连接池的参数
 11         ds.setInitialPoolSize(5); // 初始连接数
 12         ds.setMaxPoolSize(10); // 最大连接数
 13         ds.setCheckoutTimeout(2000); // 最长等待时间,单位:毫秒
 14         ds.setMaxIdleTime(1000); // 最长空闲等待时间
 15         // 4. 得到连接对象
 16         for (int i = 1; i <= 11; i++) {
 17             Connection conn = ds.getConnection();
 18             System.out.println("" + i + "个连接:" + conn);
 19             //第5个连接释放
 20             if (i ==5) {
 21                 conn.close();
 22             }
 23         }
 24     }
c3po连接池使用

使用配置文件配置参数:   
    1. 使用配置文件的好处:
        1) 因为所有的这些配置参数都写在源码中,以后修改不方便。
        2) 配置与源码是耦合在一起
   
    2. 配置文件的要求:
        1) 文件名:c3p0-config.xml
        2) 位置:放在类路径下,放在src目录下
        3) 在一个配置文件中,可以有多个配置:
            3.1) 默认配置:如果没有指定配置名,则使用默认配置
            3.2) 命名配置:如果指定了配置名,则使用指定的配置
   
    3. 多个不同配置的好处:
        1) 可以使用不同的连接池的配置参数
        2) 可以连接不同的数据库。如:db1, db2
        3) 可以使用不同厂商的数据库,如:MySQL,Oracle

  2. C3P0连接池的工具类:
      1).    创建私有静态数据源成员变量
      2).    创建公有的得到数据源的方法
      3).    创建得到连接对象的方法

  1 /**
 2  * 连接池的工具类
 3  *
 4  * @author NewBoy
 5  *
 6  */
  7 public class C3P0Util {
  8     /**
 9      * 1. 创建私有静态数据源成员变量
 10      */
 11     private static ComboPooledDataSource ds = new ComboPooledDataSource();
 12 
 13     /**
 14      * 2. 创建公有的得到数据源的方法
 15      * @return
 16      */
 17     public static DataSource getDataSource() {
 18         return ds;
 19     }
 20 
 21     /**
 22      * 3. 创建得到连接对象的方法
 23      * @return
 24      */
 25     public static Connection getConnection() {
 26         try {
 27             return ds.getConnection();
 28         } catch (SQLException e) {
 29             e.printStackTrace();
 30         }
 31         return null;
 32     }
 33 
 34 }
c3po工具类

 

DBCP连接池:  (DataBase Connection Pool 数据库连接池)

    1) 厂商:apache基金组织
    2) 开放源代码,免费
    3) Tomcat(Web服务器),默认使用的就是DBCP连接池

3. 使用步骤:

    1) 下载包
        commons-dbcp-1.4.jar   数据库连接池的核心包
        commons-pool-1.5.6.jar  辅导支持包
    2) 编写代码,创建连接池
        public class BasicDataSource implements DataSource
    3) 设置参数
        3.1) 数据库的连接参数
        3.2) 连接池的参数
    4) 通过数据源得到连接对象

  1         public class Demo1 {
  2 
  3             public static void main(String[] args) throws SQLException {
  4                 // 1.导包commons-dbcp-1.4.jar 数据库连接池的核心包 commons-pool-1.5.6.jar 辅导支持包
  5                 // 2) 编写代码,创建连接池
  6                 BasicDataSource ds = new BasicDataSource();
  7                 // 3) 设置参数
  8                 // 3.1) 数据库的连接参数(用户名,密码,URL,驱动)
  9                 ds.setUsername("root");
 10                 ds.setPassword("root");
 11                 ds.setUrl("jdbc:mysql://localhost:3306/day25");
 12                 ds.setDriverClassName("com.mysql.jdbc.Driver");
 13                 // 3.2) 连接池的参数(初始连接数,最大连接数,最长等待时间,最大等待个数)
 14                 ds.setInitialSize(5);
 15                 ds.setMaxActive(10);
 16                 ds.setMaxWait(2000);
 17                 ds.setMaxIdle(3);
 18                 // 4) 通过数据源得到连接对象
 19                 for (int i = 1; i <=11; i++) {
 20                     //Cannot get a connection, pool error Timeout waiting for idle object
 21                     Connection conn = ds.getConnection();
 22                     System.out.println("" + i + "个连接:" + conn.hashCode());
 23                     if (i == 5) {
 24                         conn.close();  //关闭了一个连接
 25                     }
 26                 }
 27             }
 28         }
dbcp示例

DBCP使用配置文件加载
    1. 配置文件
        文件名:xxx.properties
        内容:属性名=属性值
           
        1) 属性名:与set方法的名字相同,去掉set,首字母小写,如:setInitialSize 写成 initialSize
        2) 位置:建议放在src目录下,使用类加载器得到资源文件   

  1 # database connection information
  2 username=root
  3 password=root
  4 url=jdbc:mysql://localhost:3306/day25
  5 driverClassName=com.mysql.jdbc.Driver
  6 # database connect pool information
  7 initialSize=5
  8 maxActive=10
  9 maxWait=2000
 10 maxIdle=3
dbcp配置文件
  1 代码要点:
  2         1) 使用Properties类加载属性文件
  3         2) 通过类路径加载输入流
  4         3) 通过工厂对象的静态方法,得到DataSource连接池对象
  5         4) 通过BasicDataSource类得到连接对象
  6 
  7 代码:
  8     public static void main(String[] args) throws Exception {
  9         // 1) 使用Properties类加载属性文件
 10         Properties info = new Properties();
 11         // 2) 通过类路径加载输入流
 12         info.load(Demo2.class.getClassLoader().getResourceAsStream("dbcp.properties"));
 13         // 3) 通过工厂对象的静态方法,得到DataSource连接池对象
 14         BasicDataSource ds = (BasicDataSource) BasicDataSourceFactory.createDataSource(info);
 15         // 4) 通过BasicDataSource类得到连接对象
 16         for (int i = 1; i <= 11; i++) {
 17             Connection conn = ds.getConnection();
 18             System.out.println(conn.hashCode());
 19             //释放一个
 20             if (i==3) {
 21                 conn.close();
 22             }
 23         }
 24     }
dbcp示例

DbUtils工具

    1. 组织:    apache基金会
    2. 特点:
        1) 对JDBC进行封装,学习成本低,容易上手。
        2) 效率接近于直接使用JDBC的代码
        3) 几乎所有增删改查操作,都可以一句话搞定

 

一、主要类介绍
    1. 导入jar包:commons-dbutils-1.6.jar
   
    2. DbUtils类:
        1) 所有的方法都是静态方法
        2) 一组释放资源的方法
        static void    close(Connection conn)
        static void    close(ResultSet rs)
        static void    close(Statement stmt)
        static void    closeQuietly(Connection conn)
        static void    closeQuietly(Connection conn, Statement stmt, ResultSet rs)
   
    3. QueryRunner类(重点):
        进行增删改查的类
       
    4.    ResultSetHandler接口:
        用于处理查询的结果集,并且对结果集再次进行封装。
        ResultSet  ->  List<Student>

二. QueryRunner类的主要方法
    1. 方式一:
        1) 传入数据源的构造方法:
            QueryRunner(DataSource ds)
           
        2) 增删改的方法
            int    update(String sql) SQL语句
            int    update(String sql, Object... params)  SQL语句中有多个占位符,参数用来替换占位符的真实的值
            int    update(String sql, Object param) SQL语句中只有一个占位符,参数用来替换占位符的真实的值
            返回影响的行数
           
        3) 无需关闭连接
            因为update方法的内部已经关闭了连接对象

  1         public class Demo1 {
  2             // 1.创建QueryRunner类,在构造方法中传入了数据源
  3             QueryRunner runner = new QueryRunner(C3P0Util.getDataSource());
  4 
  5             @Test
  6             public  void testAdd() throws SQLException {
  7                 // 2. 向数据库中添加一条记录
  8                 runner.update("insert into student (name,gender,birthday) values (?,?,?)", "唐僧", "",
  9                         java.sql.Date.valueOf("2000-11-11"));
 10             }
 11 
 12             @Test
 13             public void testUpdate() throws SQLException {
 14                 //将id为2的学生,性别改成女
 15                 runner.update("update student set gender=? where id=?", "", 2);
 16             }
 17 
 18             @Test
 19             public void testDelete() throws SQLException {
 20                 //删除姓名为:龟仙人记录
 21                 runner.update("delete from student where name=?", "龟仙人");
 22             }
 23         }
daUtils

     2. 方式二:
        1) 无参的构造方法:new QueryRunner()
       
        2) 增删改的方法
            传入了连接对象
            int    update(Connection conn, String sql)  只有SQL语句
            int    update(Connection conn, String sql, Object... params)  多个参数,有多个占位符
            int    update(Connection conn, String sql, Object param) 一个参数,一个占位符

        3) 关闭连接
            需求自己手动关闭连接

  1         // 创建QueryRunner类
  2         QueryRunner runner = new QueryRunner();
  3 
  4         @Test
  5         public void testAdd() throws SQLException {
  6             // 得到连接对象
  7             Connection conn = C3P0Util.getConnection();
  8             // 添加1条记录
  9             int row = runner.update(conn, "insert into student(name,gender,birthday) values (?,?,?)", "小乔", "",
 10                     java.sql.Date.valueOf("2000-03-20"));
 11             //连接对象需要自己关闭
 12             DbUtils.close(conn);
 13             System.out.println(row);
 14         }
daUtils

    3. 查询有关的方法(需要时实现ResultSetHandler接口)
        1) 没有连接对象的
        <T> T    query(String sql, ResultSetHandler<T> rsh)
            传入SQL语句和结果集的处理类
           
        <T> T    query(String sql, ResultSetHandler<T> rsh, Object... params)
            sql: SQL语句
            rsh:结果集处理类
            params:替换占位符的参数
       
        2) 有连接对象的
        <T> T    query(Connection conn, String sql, ResultSetHandler<T> rsh)
        <T> T    query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)

三. ResultSetHandler接口
    1. 方法:
        T    handle(ResultSet rs) 将结果集转成一个对象

  1  实现类:
  2         示例:查询学生信息表中1条记录
  3 
  4         public class Demo3 {
  5             //创建QueryRunner对象
  6             QueryRunner runner = new QueryRunner(C3P0Util.getDataSource());
  7 
  8             @Test
  9             public void testQueryStudent() throws SQLException{
 10                 //通过id查询一个学生
 11                 Student student = runner.query("select * from student where id=?", new StudentHandler(), 3);
 12                 System.out.println(student);
 13             }
 14         }
 15 
 16         public class StudentHandler implements ResultSetHandler<Student> {
 17             @Override
 18             public Student handle(ResultSet rs) throws SQLException {
 19                 //如果有结果集
 20                 Student student = new Student();
 21                 if (rs.next()) {
 22                     student.setId(rs.getInt("id"));
 23                     student.setName(rs.getString("name"));
 24                     student.setGender(rs.getString("gender"));
 25                     student.setBirthday(rs.getDate("birthday"));
 26                 }
 27                 return student;
 28             }
 29         }
查询学生表的一条记录

     2. 常用的实现类(已经实现了ResultSetHandler接口):
        1) 封装成JavaBean:查询一条记录的时候
            前提:表的列名与类的属性名相同
            BeanHandler<>();
           
        2) 封装成List<JavaBean>
            BeanListHandler<>();
            查询多条记录的时候
           
        3) 单行单列:用于聚合函数查询
            ScalarHandler<>();

  1         public class Demo3 {
  2 
  3             // 创建QueryRunner对象
  4             QueryRunner runner = new QueryRunner(C3P0Util.getDataSource());
  5 
  6             @Test
  7             public void testQueryStudent() throws SQLException {
  8                 // 通过id查询一个学生
  9                 Student student = runner.query("select * from student where id=?", new StudentHandler(), 3);
 10                 System.out.println(student);
 11             }
 12 
 13             @Test
 14             public void testQueryStudent2() {
 15                 // 通过id查询一个学生
 16                 try {
 17                     Student student = runner.query("select * from student where id=?", new BeanHandler<Student>(Student.class),
 18                             2);
 19                     System.out.println(student);
 20                 } catch (SQLException e) {
 21                     e.printStackTrace();
 22                 }
 23             }
 24 
 25             // 查询多个学生
 26             @Test
 27             public void testQueryStudents() {
 28                 try {
 29                     List<Student> students = runner.query("select * from student", new BeanListHandler<Student>(Student.class));
 30                     for (Student student : students) {
 31                         System.out.println(student);
 32                     }
 33                 } catch (SQLException e) {
 34                     e.printStackTrace();
 35                 }
 36             }
 37 
 38             // 查询聚合函数: 查询女生的个数
 39             @Test
 40             public void testQueryGender() {
 41                 //java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
 42                 try {
 43                     long num = runner.query("select count(*) from student where gender=?", new ScalarHandler<Long>(), "");
 44                     System.out.println(num);
 45                 } catch (SQLException e) {
 46                     e.printStackTrace();
 47                 }
 48             }
 49         }
结果集


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM