最近項目開發遇到一個問題,當數據量過大時會導致系統崩潰,經過排查,發現是每一次操作數據庫都建立一次數據連接,當數據量太大,就會導致程序無法負載從而宕機。
而后進行代碼改造,改用數據庫連接池。目前使用數據庫連接池有兩種方式,使用配置文件以及不使用配置文件!
第一種: 不使用配置文件
先決條件: 導入c3p0.jar包
代碼如下:
package com.wk.cl.jxnx.esb.util;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.wk.cl.common.util.CfgTool;
import java.beans.PropertyVetoException;
import java.sql.*;
/**
* @title 數據庫操作
* @description 數據庫操作
* @since Java5
*/
public class JDBCUtil {
public static String driver = CfgTool.getProjectPropterty("esb.db.jdbc.driver");
public static String url = CfgTool.getProjectPropterty("esb.db.jdbc.url");
public static String user = CfgTool.getProjectPropterty("esb.db.jdbc.user");
public static String password = CfgTool.getProjectPropterty("jxnx.esb.db.jdbc.password");
private static JDBCUtil dbPoll;
private ComboPooledDataSource dbSource;
//靜態代碼塊,一開始我們就執行構造函數加載配置信息
static {
dbPoll = new JDBCUtil();
}
private JDBCUtil() {
try{
dbSource = new ComboPooledDataSource();
dbSource.setUser(user);
dbSource.setPassword(password);
dbSource.setJdbcUrl(url);
dbSource.setDriverClass(driver);
dbSource.setInitialPoolSize(1);
dbSource.setMinPoolSize(2);
dbSource.setMaxPoolSize(10);
dbSource.setMaxStatements(50);
dbSource.setMaxIdleTime(60);
}catch (PropertyVetoException e){
throw new RuntimeException(e);
}
}
//獲取實例
public final static JDBCUtil getInstance(){
return dbPoll;
}
/**
* 獲取數據庫連接
* @param url url
* @param user 用戶名
* @param password 密碼
* @return 數據庫連接
* @throws SQLException
*/
public final Connection getConnection(String url, String user, String password) throws SQLException {
//不使用連接池連接方式
// try {
// Class.forName(driver);
// } catch (ClassNotFoundException e) {
// logger.error("JDBC 驅動加載異常 :[{}]",e.getMessage());
// }
// return DriverManager.getConnection(url, user, password);
try{
return dbSource.getConnection();
}catch (SQLException e){
throw new RuntimeException("無法獲取連接", e);
}
}
/**
* 釋放數據庫相關對象
*
* @param rs 結果集
* @param pstmt 聲明
* @param conn 連接
*/
public static void free(ResultSet rs, PreparedStatement pstmt, Connection conn) {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (pstmt != null) {
pstmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
if (!conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
}
第二種: 使用properties文件
新建一個配置文件:c3p0.properties (注意:名字是固定的。c3p0默認只認識這個名字),具體配置如下:
c3p0.driverClass=com.ibm.db2.jcc.DB2Driver c3p0.jdbcUrl=jdbc:db2://10.1.1.232:50000/cltest c3p0.user=db2inst1 c3p0.password=db2inst1
接下來新建C3P0Demo類
/**
* Title: C3P0Demo.java
* File Description:
* @copyright: 2018
* @company: CORSWORK
* @author: guojw
* @version: 1.0
* @date: 2018年11月9日
*/
package com.wk.cl.jxnx.esb.util;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
/**
* Class Description:
* @author guojw
* 2018年11月9日
*/
public class C3P0Demo {
public void getConByC3P0() throws SQLException
{
DataSource ds = new ComboPooledDataSource();//c3p0自己去讀配置文件了,我們啥也不干
Connection conn = ds.getConnection(); //線程池建立連接
System.out.println("conn:"+conn);
String sql = "SELECTS * FROM SERV_AUTHORIZATION";
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
while(rs.next())
{
System.out.println(rs.getString(1));
System.out.println(rs.getString(2));
System.out.println(rs.getString(3));
}
//關閉連接
rs.close();
pstmt.close();
conn.close();// 連接還給連接池,而不是關閉連接
}
}
