日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

c3p0连接池用法

發布時間:2023/11/27 生活经验 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c3p0连接池用法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  使用連接池的時候并不是在代碼中不用獲取/釋放數據庫連接,而是在代碼中向連接池申請/釋放連接,對于代碼而言,可以把連接池看成數據庫。

換句話說,連接池就是數據庫的代理,之所以要使用這個代理是因為直接向數據庫申請/釋放連接是要降低性能的:如果每一次數據訪問請求都必須經歷建立數據庫連接、打開數據庫、存取數據和關閉數據庫連接等步驟,而連接并打開數據庫是一件既消耗資源又費時的工作,那么頻繁發生這種數據庫操作時,系統的性能必然會急劇下降。
連接池的作用是自己維護數據庫連接,數據庫連接池的主要操作如下:
  (1)建立數據庫連接池對象(服務器啟動)。
  (2)按照事先指定的參數創建初始數量的數據庫連接(即:空閑連接數)。
  (3)對于一個數據庫訪問請求,直接從連接池中得到一個連接。如果數據庫連接池對象中沒有空閑的連接,且連接數沒有達到最大(即:最大活躍連接數),創建一個新的數據庫連接。
  (4)存取數據庫。
  (5)關閉數據庫,釋放所有數據庫連接(此時的關閉數據庫連接,并非真正關閉,而是將其放入空閑隊列中。如實際空閑連接數大于初始空閑連接數則釋放連接)。
  (6)釋放數據庫連接池對象(服務器停止、維護期間,釋放數據庫連接池對象,并釋放所有連接)。

  從連接池獲取的連接connection跟JDK中的connection有點不同,前者的close方法并沒有關閉與數據庫的連接,而是將連接返回到池中,這樣就可以復用了。如果不調用close方法的話拿就失去了使用連接池的意義了。

  開源連接池有很多:DBCP、C3P0、Proxool 、 BoneCP等

  C3P0是一個開放源代碼的JDBC連接池,它在lib目錄中與Hibernate一起發布,包括了實現jdbc3和jdbc2擴展規范說明的Connection 和Statement 池的DataSources 對象。

  1. 下載c3p0的jar,并添加log4j.jar.
  2. 采用ThreadLocal線程局部變量保證線程安全.

使用連接池和不使用連接池時的性能差異簡單的C3P0使用測試示例

package com.lnbdqn;import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;public final class ConnectionManager {private static ConnectionManager instance;private static ComboPooledDataSource dataSource;private ConnectionManager() throws SQLException, PropertyVetoException {dataSource = new ComboPooledDataSource();dataSource.setUser("loux");dataSource.setPassword("loux");dataSource.setJdbcUrl("jdbc:oracle:thin:@192.168.100.70:1521:orcl");dataSource.setDriverClass("oracle.jdbc.driver.OracleDriver");dataSource.setInitialPoolSize(5);dataSource.setMinPoolSize(1);dataSource.setMaxPoolSize(10);dataSource.setMaxStatements(50);dataSource.setMaxIdleTime(60);}public static final ConnectionManager getInstance() {if (instance == null) {try {instance = new ConnectionManager();} catch (Exception e) {e.printStackTrace();}}return instance;}public synchronized final Connection getConnection() {Connection conn = null;try {conn = dataSource.getConnection();} catch (SQLException e) {e.printStackTrace();}return conn;}
}
package com.lnbdqn;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;import oracle.jdbc.pool.OracleDataSource;public class ConnectionDemo {public static void main(String[] args) throws SQLException {System.out.println("使用連接池................................");for (int i = 0; i < 20; i++) {long beginTime = System.currentTimeMillis();Connection conn = ConnectionManager.getInstance().getConnection();try {PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM t_fmscpy200");ResultSet rs = pstmt.executeQuery();while (rs.next()) {}} catch (SQLException e) {e.printStackTrace();} finally {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}long endTime = System.currentTimeMillis();System.out.println("第" + (i + 1) + "次執行花費時間為:" + (endTime - beginTime));}System.out.println("不使用連接池................................");for (int i = 0; i < 20; i++) {long beginTime = System.currentTimeMillis();OracleDataSource ods = new OracleDataSource();ods.setUser("loux");ods.setPassword("loux");ods.setURL("jdbc:oracle:thin:@192.168.100.70:1521:orcl");Connection conn = ods.getConnection();try {PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM table_name");ResultSet rs = pstmt.executeQuery();while (rs.next()) {// do nothing...
                }} catch (SQLException e) {e.printStackTrace();} finally {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}long endTime = System.currentTimeMillis();System.out.println("第" + (i + 1) + "次執行花費時間為:"+ (endTime - beginTime));}}
}
控制臺輸出的結果為:使用連接池................................
第1次執行花費時間為:1469
第2次執行花費時間為:0
第3次執行花費時間為:16
第4次執行花費時間為:0
第5次執行花費時間為:0
第6次執行花費時間為:15
第7次執行花費時間為:0
第8次執行花費時間為:0
第9次執行花費時間為:0
第10次執行花費時間為:0
第11次執行花費時間為:16
第12次執行花費時間為:0
第13次執行花費時間為:0
第14次執行花費時間為:0
第15次執行花費時間為:0
第16次執行花費時間為:16
第17次執行花費時間為:0
第18次執行花費時間為:0
第19次執行花費時間為:15
第20次執行花費時間為:0
不使用連接池................................
第1次執行花費時間為:47
第2次執行花費時間為:31
第3次執行花費時間為:32
第4次執行花費時間為:46
第5次執行花費時間為:32
第6次執行花費時間為:31
第7次執行花費時間為:47
第8次執行花費時間為:31
第9次執行花費時間為:47
第10次執行花費時間為:31
第11次執行花費時間為:47
第12次執行花費時間為:31
第13次執行花費時間為:32
第14次執行花費時間為:46
第15次執行花費時間為:47
第16次執行花費時間為:32
第17次執行花費時間為:46
第18次執行花費時間為:47
第19次執行花費時間為:32
第20次執行花費時間為:31
可以看出,在使用連接池時,第一次執行花費的時間稍長,因為第一次初始化操作需要創建多個連接并放入池中,以后使用時將會大大縮短執行時間。
在不使用連接池時,每次花費的時間都比較長。

下面是一個service層的銀行轉賬方法

    public void transferMoneyNew(int from,int to,float money) throws Exception{AccountDAOImpl dao = null;try{/*完成的功能:1.從數據源中獲取Connection2.開啟事務3. 放到線程上*/JDBCUtils.startTransaction();  //創建DAOdao = new AccountDAOImpl();     //獲取賬戶信息Account fromAccount = dao.findAccountByID(from);Account toAccount = dao.findAccountByID(to);//扣錢和加錢fromAccount.setMoney(fromAccount.getMoney() - money);toAccount.setMoney(toAccount.getMoney() + money);        //更新數據庫
            dao.updateAccount(fromAccount);       //產生錯誤int i=1/0;       dao.updateAccount(toAccount);        //提交
            JDBCUtils.commit();}catch(Exception ex){JDBCUtils.rollback();throw new ServiceException(ex);}finally{JDBCUtils.release();}}

JDBCUtils類
public class JDBCUtils {//連接的容器public static ThreadLocal<Connection> container = new ThreadLocal<Connection>();//定義c3p0 數據源private static DataSource ds = new ComboPooledDataSource();/*完成的功能:1.從數據源中獲取Connection2.開啟事務3. 放到線程上*/public static void startTransaction() throws SQLException{Connection conn  = container.get();//當前線程上是否已經存在連接if(conn == null){conn = ds.getConnection();}//開啟事務conn.setAutoCommit(false);//放到當前線程上
        container.set(conn);}//提交當前線程上的連接public static void commit() throws SQLException{Connection conn  = container.get();if(conn != null){conn.commit();}}//回滾當前線程上的連接public static void  rollback() throws SQLException{Connection conn  = container.get();if(conn != null){conn.rollback();}}//釋放當前線程上的連接public static void release() throws SQLException{Connection conn  = container.get();if(conn != null){//從當前線程上,拿掉連接
            container.remove();conn.close();}        }//返回數據源public static DataSource getDataSource(){return ds;}public static Connection getConnection() throws SQLException {return ds.getConnection();}//釋放資源public static void release(Connection conn,Statement st,ResultSet rs){if(rs != null){try {rs.close();} catch (SQLException e) {throw new RuntimeException(e);}finally{rs = null;}}   if(st != null){try {st.close();} catch (SQLException e) {throw new RuntimeException(e);}finally{st = null;}}if(conn != null){try {conn.close();} catch (SQLException e) {throw new RuntimeException(e);}finally{conn = null;}}        }
}

OSChina 的 DBManager 類?管理數據庫連接

public class DBManager {private final static Log log = LogFactory.getLog(DBManager.class);private final static ThreadLocal<Connection> conns = new ThreadLocal<Connection>();private static DataSource dataSource;private static boolean show_sql = false;static {initDataSource(null);}/*** 初始化連接池* @param props* @param show_sql*/private final static void initDataSource(Properties dbProperties) {try {if(dbProperties == null){dbProperties = new Properties();dbProperties.load(DBManager.class.getResourceAsStream("db.properties"));}Properties cp_props = new Properties();for(Object key : dbProperties.keySet()) {String skey = (String)key;if(skey.startsWith("jdbc.")){String name = skey.substring(5);cp_props.put(name, dbProperties.getProperty(skey));if("show_sql".equalsIgnoreCase(name)){show_sql = "true".equalsIgnoreCase(dbProperties.getProperty(skey));}}}dataSource = (DataSource)Class.forName(cp_props.getProperty("datasource")).newInstance();if(dataSource.getClass().getName().indexOf("c3p0")>0){//Disable JMX in C3P0System.setProperty("com.mchange.v2.c3p0.management.ManagementCoordinator", "com.mchange.v2.c3p0.management.NullManagementCoordinator");}log.info("Using DataSource : " + dataSource.getClass().getName());BeanUtils.populate(dataSource, cp_props);Connection conn = getConnection();DatabaseMetaData mdm = conn.getMetaData();log.info("Connected to " + mdm.getDatabaseProductName() + " " + mdm.getDatabaseProductVersion());closeConnection();} catch (Exception e) {throw new DBException(e);}}/*** 斷開連接池*/public final static void closeDataSource(){try {dataSource.getClass().getMethod("close").invoke(dataSource);} catch (NoSuchMethodException e){ } catch (Exception e) {log.error("Unabled to destroy DataSource!!! ", e);}}public final static Connection getConnection() throws SQLException {Connection conn = conns.get();if(conn ==null || conn.isClosed()){conn = dataSource.getConnection();conns.set(conn);}return (show_sql && !Proxy.isProxyClass(conn.getClass()))?new _DebugConnection(conn).getConnection():conn;}/*** 關閉連接*/public final static void closeConnection() {Connection conn = conns.get();try {if(conn != null && !conn.isClosed()){conn.setAutoCommit(true);conn.close();}} catch (SQLException e) {log.error("Unabled to close connection!!! ", e);}conns.set(null);}/*** 用于跟蹤執行的SQL語句* @author Winter Lau*/static class _DebugConnection implements InvocationHandler {private final static Log log = LogFactory.getLog(_DebugConnection.class);private Connection conn = null;public _DebugConnection(Connection conn) {this.conn = conn;}/*** Returns the conn.* @return Connection*/public Connection getConnection() {return (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces(), this);}public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {try {String method = m.getName();if("prepareStatement".equals(method) || "createStatement".equals(method))log.info("[SQL] >>> " + args[0]);                return m.invoke(conn, args);} catch (InvocationTargetException e) {throw e.getTargetException();}}}}
# DataSource
jdbc.datasource=com.mchange.v2.c3p0.ComboPooledDataSource
jdbc.show_sql=true# Database Configurations
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/oscdb
jdbc.user=root
jdbc.password=xxxx
jdbc.maxPoolSize=100
jdbc.minPoolSize=2
jdbc.initialPoolSize=2
jdbc.acquireIncrement=2
jdbc.maxStatements=1000
jdbc.maxIdleTime=300
jdbc.checkoutTimeout=5000

參數配置例子

package com.wb.db;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
* 采用ThreadLocal線程局部變量保證線程安全
* @author hemes1314
*/
public class C3p0Pool {public static ThreadLocal connectionHolder = new ThreadLocal(); private static DataSource dataSource;public C3p0Pool(){   }   public static Connection getConnection() {Connection conn = (Connection) connectionHolder.get();//如果在當前線程中沒有綁定相應的Connectionif(conn==null){if (dataSource == null) {   initDataSource();}   try {   conn = dataSource.getConnection(); //將Connection設置到ThreadLocal線程變量中
             connectionHolder.set(conn); } catch (SQLException e) {   // TODO Auto-generated catch block   
             e.printStackTrace();   } }return conn;   }public static void closeConnection(){Connection conn = (Connection) connectionHolder.get();if(conn!=null){try {conn.close();//從ThreadLocal中清除Connection
     connectionHolder.remove();} catch (SQLException e) {// TODO Auto-generated catch block
     e.printStackTrace();}}}public static void initDataSource(){   String driverClassName=null;   String url=null;   String username=null;   String password=null;   int initialPoolSize=3;   int maxPoolSize=15;int minPoolSize=5;int acquireRetryDelay=1000;int maxIdleTime=60;Configuration config=new Configuration("oraConn.properties");driverClassName = config.getValue("driver");   url = config.getValue("url");username = config.getValue("user");password = config.getValue("password");   initialPoolSize = Integer.parseInt(config.getValue("initialPoolSize").trim());       maxPoolSize = Integer.parseInt(config.getValue("maxPoolSize").trim());minPoolSize = Integer.parseInt(config.getValue("minPoolSize").trim());maxIdleTime = Integer.parseInt(config.getValue("maxIdleTime").trim()); ComboPooledDataSource cpds = new ComboPooledDataSource();    try {cpds.setDriverClass(driverClassName);} catch (PropertyVetoException e) {// TODO Auto-generated catch block
    e.printStackTrace();}cpds.setUser(username);   cpds.setPassword(password);   cpds.setJdbcUrl(url);//初始化時獲取三個連接,取值應在minPoolSize與maxPoolSize之間。Default: 3 initialPoolSize   
    cpds.setInitialPoolSize(initialPoolSize);   //連接池中保留的最大連接數。Default: 15 maxPoolSize   
    cpds.setMaxPoolSize(maxPoolSize);//連接池中保留的最小連接數。   
    cpds.setMinPoolSize(minPoolSize);//獲得連接的最大等待毫秒數。Default: 1000 acquireRetryDelay
    cpds.setAcquireRetryDelay(acquireRetryDelay);//最大空閑時間,60秒內未使用則連接被丟棄。若為0則永不丟棄。Default: 0 maxIdleTime   
    cpds.setMaxIdleTime(maxIdleTime);//當連接池中的連接耗盡的時候c3p0一次同時獲取的連接數。Default: 3 acquireIncrement   //cpds.setAcquireIncrement(3);   //每60秒檢查所有連接池中的空閑連接。Default: 0 idleConnectionTestPeriod   //cpds.setIdleConnectionTestPeriod(60);//連接關閉時默認將所有未提交的操作回滾。Default: false autoCommitOnClose   //cpds.setAutoCommitOnClose(true);//JDBC的標準參數,用以控制數據源內加載的PreparedStatements數量。但由于預緩存的statements屬于單個connection而不是整個連接池。所以設置這個參數需要考慮到多方面的因素。如果maxStatements與maxStatementsPerConnection均為0,則緩存被關閉。Default: 0 //cpds.setMaxStatements(1);//maxStatementsPerConnection定義了連接池內單個連接所擁有的最大緩存statements數//cpds.setMaxStatementsPerConnection(100);//定義所有連接測試都執行的測試語句。在使用連接測試的情況下這個一顯著提高測試速度。注意:測試的表必須在初始數據源的時候就存在。Default: null preferredTestQuery   //cpds.setPreferredTestQuery("select sysdate from dual");   // 因性能消耗大請只在需要的時候使用它。如果設為true那么在每個connection提交的   // 時候都將校驗其有效性。建議使用idleConnectionTestPeriod或automaticTestTable   // 等方法來提升連接測試的性能。Default: false testConnectionOnCheckout   //cpds.setTestConnectionOnCheckout(true);//如果設為true那么在取得連接的同時將校驗連接的有效性。Default: false testConnectionOnCheckin   //cpds.setTestConnectionOnCheckin(true);   //定義在從數據庫獲取新連接失敗后重復嘗試的次數。Default: 30 acquireRetryAttempts   //cpds.setAcquireRetryAttempts(30);     //獲取連接失敗將會引起所有等待連接池來獲取連接的線程拋出異常。但是數據源仍有效   //保留,并在下次調用getConnection()的時候繼續嘗試獲取連接。如果設為true,那么在嘗試   //獲取連接失敗后該數據源將申明已斷開并永久關閉。Default: false breakAfterAcquireFailure   //cpds.setBreakAfterAcquireFailure(false);   dataSource = cpds;        }/* 用于測試連接狀態的方法*/public static void main(String[] args) {ComboPooledDataSource ds=(ComboPooledDataSource)dataSource;   try {System.out.println(ds.getConnection());} catch (SQLException e) {// TODO Auto-generated catch block
    e.printStackTrace();}//System.out.println(ds.getInitialSize());   //System.out.println(ds.getNumActive());   //System.out.println(ds.getNumIdle());   //System.out.println(ds.getDefaultAutoCommit());
}}

轉載于:https://www.cnblogs.com/janko208/archive/2012/08/27/2658628.html

總結

以上是生活随笔為你收集整理的c3p0连接池用法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。