Java操作數據庫——使用連接池連接數據庫


Java操作數據庫——使用連接池連接數據庫

摘要:本文主要學習了如何使用JDBC連接池連接數據庫。

傳統方式和連接池方式

傳統方式的步驟

使用傳統方式在Java中使用JDBC連接數據庫,完成一次數據庫的操作,一般有以下幾個步驟:

加載驅動。

建立連接。

執行SQL語句。

釋放連接。

傳統方式的弊端

每一次對數據庫的操作都要建立一次連接,並且會將得到的Connection對象加載到內存中,導致消耗了大量的內存和時間。如果短時間有很多需要進行建立連接的操作,會導致占用很多系統資源,甚至會導致服務器崩潰。

同建立連接相對應,每次使用都需要手動釋放連接,如果忘記釋放連接或者程序出現異常未能成功釋放,會導致內存泄露。

此外,傳統方式並不能控制連接的數量,如果連接的人數過多,會導致無限制的創建連接對象,導致內存開銷過大,服務器崩潰。

連接池的步驟

創建連接池並配置連接屬性。

使用連接池獲取連接。

連接池的優勢

每次需要連接數據庫時,不需要建立連接,而是通過連接池獲取,由連接池提供連接。

在使用完連接后,不需要手動釋放連接,而是交由連接池釋放連接。

可以通過連接池控制連接的數量,在連接池里的連接可多次重復使用,避免了無限制創建連接的問題。

使用連接池

使用C3P0連接池

C3P0是一個開放源代碼的JDBC連接池,它在lib目錄中與Hibernate一起發布,包括實現了數據源和JNDI綁定,支持JDBC3規范和JDBC2的標准擴展。目前使用它的開源項目有Hibernate,Spring等。

導入jar包:

1 c3p0-0.9.5.2.jar

在當前項目的代碼根目錄 src 下新建名為 c3p0-config.xml 的配置文件,注意文件名稱不可改變,內容如下:

 1 <c3p0-config>
 2     <!-- 連接名稱 -->
 3     <named-config name="mysql">
 4         <!-- 接數據庫的驅動類名 -->
 5         <property name="driverClass">com.mysql.jdbc.Driver</property>
 6         <!-- 連接屬性 -->
 7         <property name="jdbcUrl">jdbc:mysql://192.168.35.128:3306/demo</property>
 8         <property name="user">root</property>
 9         <property name="password">123456</property>
10         <!-- 當連接池用完時等待獲取新連接的時間,超時后將拋出SQLException,單位毫秒,如設為0則無限期等待。默認為0。 -->
11         <property name="checkoutTimeout">5000</property>
12         <!-- 當連接用盡后,一次獲取的連接個數 -->
13         <property name="acquireIncrement">2</property>
14         <!-- 初始連接數 -->
15         <property name="initialPoolSize">1</property>
16         <!-- 最小連接數 -->
17         <property name="minPoolSize">3</property>
18         <!-- 最大連接數 -->
19         <property name="maxPoolSize">5</property>
20     </named-config>
21 </c3p0-config>

程序代碼:

 1 public class TestDataPool {
 2     // 根據配置文件里的名稱創建連接池
 3     public static ComboPooledDataSource cpds = new ComboPooledDataSource("mysql");
 4     
 5     /**
 6      * 主程序
 7      */
 8     public static void main(String[] args) {
 9         // 模擬多次對數據庫的查詢操作
10         for (int i = 0; i < 6; i++) {
11             new Thread(new Runnable() {
12                 @Override
13                 public void run() {
14                     select();
15                 }
16             }, "線程" + i).start();
17         }
18     }
19     
20     /**
21      * 查詢程序
22      */
23     public static void select() {
24         Connection conn = null;
25         PreparedStatement pstmt = null;
26         ResultSet rs = null;
27         // 獲取連接並執行SQL
28         try {
29             conn = cpds.getConnection();
30             pstmt = conn.prepareStatement("select * from student where id = 906");
31             rs = pstmt.executeQuery();
32             while (rs.next()) {
33                 System.out.println(Thread.currentThread().getName() + "\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString("address"));
34             }
35         } catch (Exception e) {
36             e.printStackTrace();
37         } finally {
38             // 釋放資源
39             try {
40                 rs.close();
41             } catch (SQLException e) {
42                 e.printStackTrace();
43             }
44             try {
45                 pstmt.close();
46             } catch (SQLException e) {
47                 e.printStackTrace();
48             }
49             try {
50                 conn.close();
51             } catch (SQLException e) {
52                 e.printStackTrace();
53             }
54         }
55     }
56 }

使用DBCP連接池

DBCP是Apache上的一個Java連接池項目,是一個依賴Jakarta項目commons-pool對象池機制的數據庫連接池。DBCP可以直接的在應用程序中使用,Tomcat的數據源使用的就是DBCP。

導入jar包:

1 commons-dbcp-1.4.jar2 commons-pool-1.5.5.jar

在當前項目的代碼根目錄 src 下新建名為 dbcp.properties 的配置文件,文件名需要同代碼中引用的文件名一致,內容如下:

 1 # 接數據庫的驅動類名
 2 driverClassName=com.mysql.jdbc.Driver
 3 # 連接屬性
 4 url=jdbc:mysql://192.168.35.128:3306/demo
 5 username=root
 6 password=123456
 7 # 初始化連接數
 8 initialSize=10
 9 # 最大連接數
10 maxActive=15

程序代碼:

 1 public class TestDBCP {
 2     // 根據配置文件里的名稱創建連接池
 3     private static DataSource source = null;
 4     static {
 5         Properties pros = new Properties();
 6         InputStream is = TestDBCP.class.getClassLoader().getResourceAsStream("dbcp.properties");
 7         try {
 8             pros.load(is);
 9             source = BasicDataSourceFactory.createDataSource(pros);
10         } catch (Exception e) {
11             e.printStackTrace();
12         }
13     }
14 
15     /**
16      * 主程序
17      */
18     public static void main(String[] args) {
19         // 模擬多次對數據庫的查詢操作
20         for (int i = 0; i < 6; i++) {
21             new Thread(new Runnable() {
22                 @Override
23                 public void run() {
24                     select();
25                 }
26             }, "線程" + i).start();
27         }
28     }
29 
30     /**
31      * 查詢程序
32      */
33     public static void select() {
34         Connection conn = null;
35         PreparedStatement pstmt = null;
36         ResultSet rs = null;
37         // 獲取連接並執行SQL
38         try {
39             conn = source.getConnection();
40             pstmt = conn.prepareStatement("select * from student where id = 906");
41             rs = pstmt.executeQuery();
42             while (rs.next()) {
43                 System.out.println(Thread.currentThread().getName() + "\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString("address"));
44             }
45         } catch (Exception e) {
46             e.printStackTrace();
47         } finally {
48             // 釋放資源
49             try {
50                 rs.close();
51             } catch (SQLException e) {
52                 e.printStackTrace();
53             }
54             try {
55                 pstmt.close();
56             } catch (SQLException e) {
57                 e.printStackTrace();
58             }
59             try {
60                 conn.close();
61             } catch (SQLException e) {
62                 e.printStackTrace();
63             }
64         }
65     }
66 }

使用Druid連接池

Druid是阿里巴巴出品的數據源,而且是淘寶和支付寶專用數據庫連接池,但它不僅僅是一個數據庫連接池,它還包含一個ProxyDriver,一系列內置的JDBC組件庫,一個SQL Parser。

導入jar包:

1 druid-1.0.9.jar

在當前項目的代碼根目錄 src 下新建名為 druid.properties 的配置文件,文件名需要同代碼中引用的文件名一致,內容如下:

 1 # 接數據庫的驅動類名
 2 driverClassName=com.mysql.jdbc.Driver
 3 # 連接屬性
 4 url=jdbc:mysql://192.168.35.128:3306/demo
 5 username=root
 6 password=123456
 7 # 最大連接數
 8 maxActive=15
 9 # 最長等待時間
10 maxWait=3000
11 # 配置初始化連接數
12 initialSize=1
13 # 配置最大活動連接數
14 maxActive=10

程序代碼:

 1 public class TestDruid {
 2     // 根據配置文件里的名稱創建連接池
 3     private static DataSource source = null;
 4     static {
 5         Properties pros = new Properties();
 6         InputStream is = TestDruid.class.getClassLoader().getResourceAsStream("druid.properties");
 7         try {
 8             pros.load(is);
 9             source = DruidDataSourceFactory.createDataSource(pros);
10         } catch (Exception e) {
11             e.printStackTrace();
12         }
13     }
14 
15     /**
16      * 主程序
17      */
18     public static void main(String[] args) {
19         // 模擬多次對數據庫的查詢操作
20         for (int i = 0; i < 6; i++) {
21             new Thread(new Runnable() {
22                 @Override
23                 public void run() {
24                     select();
25                 }
26             }, "線程" + i).start();
27         }
28     }
29 
30     /**
31      * 查詢程序
32      */
33     public static void select() {
34         Connection conn = null;
35         PreparedStatement pstmt = null;
36         ResultSet rs = null;
37         // 獲取連接並執行SQL
38         try {
39             conn = source.getConnection();
40             pstmt = conn.prepareStatement("select * from student where id = 906");
41             rs = pstmt.executeQuery();
42             while (rs.next()) {
43                 System.out.println(Thread.currentThread().getName() + "\t" + rs.getString(1) + "\t" + rs.getString(2) + "\t" + rs.getString("address"));
44             }
45         } catch (Exception e) {
46             e.printStackTrace();
47         } finally {
48             // 釋放資源
49             try {
50                 rs.close();
51             } catch (SQLException e) {
52                 e.printStackTrace();
53             }
54             try {
55                 pstmt.close();
56             } catch (SQLException e) {
57                 e.printStackTrace();
58             }
59             try {
60                 conn.close();
61             } catch (SQLException e) {
62                 e.printStackTrace();
63             }
64         }
65     }
66 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM