033_jdbc-mysql数据库连接池
1. 數據庫連接實際上是客戶端和遠程數據庫服務器建立了一個socket連接, 創建過程比較耗性能和時間, 因此出現了數據庫連接池技術。
2. 數據庫連接池負責分配、管理和釋放數據庫連接, 它允許應用程序重復使用一個現有的數據庫連接,而不是再重新建立一個。這項技術能明顯提高對數據庫操作的性能。
3. 連接池基本的思想是在系統初始化的時候, 將數據庫連接作為對象存儲在內存中, 當用戶需要訪問數據庫時, 并非建立一個新的連接, 而是從連接池中取出一個已建立的空閑連接對象。使用完畢后, 用戶也并非將連接關閉, 而是將連接放回連接池中, 以供下一個請求訪問使用。而連接的建立、斷開都由連接池自身來管理。同時, 還可以通過設置連接池的參數來控制連接池中的初始連接數、連接的上下限數以及每個連接的最大使用次數、最大空閑時間等等。也可以通過其自身的管理機制來監視數據庫連接的數量、使用情況等。
4. 在Java中常用的開源的數據庫連接池有以下幾種
4.1. C3P0: 是一個開放源代碼的JDBC連接池, 包括了實現jdbc3和jdbc2擴展規范說明的Connection和Statement池的DataSources 對象。
4.2. Proxool: 是一個Java SQL Driver驅動程序, 提供了對選擇的其它類型的驅動程序的連接池封裝。可以非常簡單的移植到現存的代碼中, 完全可配置, 快速、成熟、健壯。可以透明地為現存的JDBC驅動程序增加連接池功能。
4.3. Jakarta DBCP: DBCP是一個依賴Jakartacommons-pool對象池機制的數據庫連接池。DBCP可以直接的在應用程序中使用。
4.4. 目前Proxool和DBCP以及C3P0一起, 最為常見的三種JDBC連接池技術。
4.5. 后來, Hibernate官方宣布由于Bug太多不再支持DBCP, 而推薦使用C3P0或Proxool。
5. 自己實現Java的數據庫連接池接口(DataSource)
5.1. 創建一個名稱為SunDataSource的Java工程, 使用之前的JDBCUtil.java和jdbc.properties屬性文件
5.2. 創建一個MyDataSource.java實現Java的DataSource接口
package com.lywgames.myjdbc;import java.io.PrintWriter; import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import javax.sql.DataSource; import com.lywgames.util.JDBCUtil;/*** 實現java的DataSource接口*/ public class MyDataSource implements DataSource {private List<Connection> list = new ArrayList<Connection>();/*** 對象一創建就創建10個數據庫連接對象, 放到list對象*/public MyDataSource() {for (int i = 0; i < 10; i++) {Connection conn = JDBCUtil.getConn();list.add(conn);}}// 該連接池對外公布的獲取連接的方法@Overridepublic Connection getConnection() throws SQLException {// 發現連接池的連接數量為0, 自動擴容if(list.size() == 0) {for (int i = 0; i < 10; i++) {Connection conn = JDBCUtil.getConn();list.add(conn);}}return list.remove(0);}/*** 歸還數據庫連接對象* @param conn*/public void backConnection(Connection conn) {System.out.println("歸還連接前, 連接數:" + list.size());list.add(conn);System.out.println("歸還連接后, 連接數:" + list.size());}@Overridepublic Connection getConnection(String username, String password) throws SQLException {return null;}@Overridepublic PrintWriter getLogWriter() throws SQLException {return null;}@Overridepublic int getLoginTimeout() throws SQLException {return 0;}@Overridepublic Logger getParentLogger() throws SQLFeatureNotSupportedException {return null;}@Overridepublic void setLogWriter(PrintWriter arg0) throws SQLException {}@Overridepublic void setLoginTimeout(int arg0) throws SQLException {}@Overridepublic boolean isWrapperFor(Class<?> arg0) throws SQLException {return false;}@Overridepublic <T> T unwrap(Class<T> arg0) throws SQLException {return null;}}5.3. 使用MyDataSource
package com.lywgames.myjdbc;import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; import com.lywgames.util.JDBCUtil;public class MyJDBC {public static void main(String[] args) {Connection conn = null;PreparedStatement ps = null;// 創建自己的連接池對象MyDataSource ds = new MyDataSource();try {conn = ds.getConnection();ps = conn.prepareStatement("insert into user values(null,?,?,?)");ps.setString(1, "lvbu");ps.setString(2, "123456");ps.setTimestamp(3, new Timestamp(System.currentTimeMillis()));ps.executeUpdate();} catch (SQLException e) {e.printStackTrace();} finally {JDBCUtil.release(ps);}// 歸還連接ds.backConnection(conn);} }5.4. 運行程序, 查看結果
6. 對連接進行包裝
6.1. 創建一個名稱為MyDataSourceConnectionWrap的Java工程, 使用之前的JDBCUtil.java和jdbc.properties屬性文件
6.2. 創建一個ConnectionWrap.java實現Connection接口
package com.lywgames.myjdbc;import java.sql.Array; import java.sql.Blob; import java.sql.CallableStatement; import java.sql.Clob; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.NClob; import java.sql.PreparedStatement; import java.sql.SQLClientInfoException; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.SQLXML; import java.sql.Savepoint; import java.sql.Statement; import java.sql.Struct; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.Executor;/*** 使用使用裝飾者模式, 對JDBC實際創建的Connection對象進行包裝*/ public class ConnectionWrap implements Connection {private List<Connection> list;private Connection connection;public ConnectionWrap(Connection connection, List<Connection> list) {this.connection = connection;this.list = list;}// 在Connection對象的close方法里歸還數據庫連接@Overridepublic void close() throws SQLException {System.out.println("調用close方法歸還連接前: " + list.size());this.list.add(connection);System.out.println("調用close方法歸還連接后: " + list.size());}@Overridepublic PreparedStatement prepareStatement(String sql) throws SQLException {return connection.prepareStatement(sql);}@Overridepublic PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {return null;}@Overridepublic PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {return null;}@Overridepublic PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {return null;}@Overridepublic PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {return null;}@Overridepublic PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,int resultSetHoldability) throws SQLException {return null;}@Overridepublic boolean isWrapperFor(Class<?> arg0) throws SQLException {return false;}@Overridepublic <T> T unwrap(Class<T> arg0) throws SQLException {return null;}@Overridepublic void abort(Executor executor) throws SQLException {}@Overridepublic void clearWarnings() throws SQLException {}@Overridepublic void commit() throws SQLException {}@Overridepublic Array createArrayOf(String typeName, Object[] elements) throws SQLException {return null;}@Overridepublic Blob createBlob() throws SQLException {return null;}@Overridepublic Clob createClob() throws SQLException {return null;}@Overridepublic NClob createNClob() throws SQLException {return null;}@Overridepublic SQLXML createSQLXML() throws SQLException {return null;}@Overridepublic Statement createStatement() throws SQLException {return null;}@Overridepublic Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {return null;}@Overridepublic Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {return null;}@Overridepublic Struct createStruct(String typeName, Object[] attributes) throws SQLException {return null;}@Overridepublic boolean getAutoCommit() throws SQLException {return false;}@Overridepublic String getCatalog() throws SQLException {return null;}@Overridepublic Properties getClientInfo() throws SQLException {return null;}@Overridepublic String getClientInfo(String name) throws SQLException {return null;}@Overridepublic int getHoldability() throws SQLException {return 0;}@Overridepublic DatabaseMetaData getMetaData() throws SQLException {return null;}@Overridepublic int getNetworkTimeout() throws SQLException {return 0;}@Overridepublic String getSchema() throws SQLException {return null;}@Overridepublic int getTransactionIsolation() throws SQLException {return 0;}@Overridepublic Map<String, Class<?>> getTypeMap() throws SQLException {return null;}@Overridepublic SQLWarning getWarnings() throws SQLException {return null;}@Overridepublic boolean isClosed() throws SQLException {return false;}@Overridepublic boolean isReadOnly() throws SQLException {return false;}@Overridepublic boolean isValid(int timeout) throws SQLException {return false;}@Overridepublic String nativeSQL(String sql) throws SQLException {return null;}@Overridepublic CallableStatement prepareCall(String sql) throws SQLException {return null;}@Overridepublic CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {return null;}@Overridepublic CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,int resultSetHoldability) throws SQLException {return null;}@Overridepublic void releaseSavepoint(Savepoint savepoint) throws SQLException {}@Overridepublic void rollback() throws SQLException {}@Overridepublic void rollback(Savepoint savepoint) throws SQLException {}@Overridepublic void setAutoCommit(boolean autoCommit) throws SQLException {}@Overridepublic void setCatalog(String catalog) throws SQLException {}@Overridepublic void setClientInfo(Properties properties) throws SQLClientInfoException {}@Overridepublic void setClientInfo(String name, String value) throws SQLClientInfoException {}@Overridepublic void setHoldability(int holdability) throws SQLException {}@Overridepublic void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {}@Overridepublic void setReadOnly(boolean readOnly) throws SQLException {}@Overridepublic Savepoint setSavepoint() throws SQLException {return null;}@Overridepublic Savepoint setSavepoint(String name) throws SQLException {return null;}@Overridepublic void setSchema(String schema) throws SQLException {}@Overridepublic void setTransactionIsolation(int level) throws SQLException {}@Overridepublic void setTypeMap(Map<String, Class<?>> map) throws SQLException {}}6.3. 創建一個MyDataSource.java實現DataSource接口
package com.lywgames.myjdbc;import java.io.PrintWriter; import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import javax.sql.DataSource; import com.lywgames.util.JDBCUtil;/*** 實現java的DataSource接口*/ public class MyDataSource implements DataSource {private List<Connection> list = new ArrayList<Connection>();/*** 對象一創建就創建10個數據庫連接對象, 放到list對象*/public MyDataSource() {for (int i = 0; i < 10; i++) {list.add(JDBCUtil.getConn());}}// 該連接池對外公布的獲取連接的方法@Overridepublic Connection getConnection() throws SQLException {// 發現連接池的連接數量為0, 自動擴容if(list.size() == 0) {for (int i = 0; i < 10; i++) {list.add(JDBCUtil.getConn());}}// 對之前的Connection對象進行包裝Connection connectionWrap = new ConnectionWrap(list.remove(0), list);return connectionWrap;}@Overridepublic Connection getConnection(String username, String password) throws SQLException {return null;}@Overridepublic PrintWriter getLogWriter() throws SQLException {return null;}@Overridepublic int getLoginTimeout() throws SQLException {return 0;}@Overridepublic Logger getParentLogger() throws SQLFeatureNotSupportedException {return null;}@Overridepublic void setLogWriter(PrintWriter arg0) throws SQLException {}@Overridepublic void setLoginTimeout(int arg0) throws SQLException {}@Overridepublic boolean isWrapperFor(Class<?> arg0) throws SQLException {return false;}@Overridepublic <T> T unwrap(Class<T> arg0) throws SQLException {return null;}}6.4. 使用MyDataSource
package com.lywgames.myjdbc;import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; import com.lywgames.util.JDBCUtil;public class MyJDBC {public static void main(String[] args) {Connection conn = null;PreparedStatement ps = null;// 創建自己的連接池對象MyDataSource ds = new MyDataSource();try {conn = ds.getConnection();ps = conn.prepareStatement("insert into user values(null,?,?,?)");ps.setString(1, "diaochan");ps.setString(2, "123456");ps.setTimestamp(3, new Timestamp(System.currentTimeMillis()));ps.executeUpdate();} catch (SQLException e) {e.printStackTrace();} finally {JDBCUtil.release(conn, ps);}} }6.5. 運行程序, 查看結果
總結
以上是生活随笔為你收集整理的033_jdbc-mysql数据库连接池的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 030_jdbc-mysql事务
- 下一篇: 034_jdbc-mysql-C3P0