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