前言
對于spring項目,如果需要用到多數(shù)據(jù)源状答,可以直接在spirng配置多個數(shù)據(jù)源粉洼,但是這種方法比較麻煩,特別是項目整合了mybatis的情況仅财,如果我們只需要很簡單地訪問另外一個數(shù)據(jù)庫狈究,我們完全可以通過dbcp實現(xiàn)一個簡單的連接池即可。
實現(xiàn)
一開始盏求,我們可以用純粹的jdbc來連接數(shù)據(jù)庫谦炒,但是這樣,我們每次訪問數(shù)據(jù)庫风喇,都需要開啟連接和關(guān)閉連接宁改,非常浪費(fèi)資源,因此魂莫,我們可以實現(xiàn)一個簡單的連接池还蹲,用于減少這部分資源的開銷。并且耙考,我們不需要自己實現(xiàn)連接池的功能谜喊,各大廠商都已經(jīng)為我們提供了連接池的實現(xiàn),例如C3P0倦始、DBCP連接池等斗遏,我們只需在這基礎(chǔ)上二次開發(fā)即可,這里鞋邑,我們選用DBCP來實現(xiàn)我們的連接池功能诵次。
- pom.xml配置
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
- config.properties配置連接屬性
#other database
other.jdbc.driver=com.mysql.jdbc.Driver
other.jdbc.url=jdbc:mysql://localhost:3306/spring_test?useUnicode=true&characterEncoding=utf-8
other.jdbc.user=root
other.jdbc.password=root
other.initSize=1
other.maxAtive=8
other.maxWait=60000
other.maxIdle=6
other.minIdle=2
- 連接池工具類
這里使用了ThreadLocal類账蓉,主要是通過該類實現(xiàn)同步效果,防止多線程下該連接池失效逾一。
public class DbUtil {
private static final Logger log = LoggerFactory.getLogger(DbUtil.class);
/**
* 數(shù)據(jù)庫連接池
*/
private static BasicDataSource dbcp;
/**
* 為不同線程管理連接
*/
private static ThreadLocal<Connection> threadLocal;
static {
try {
dbcp = new BasicDataSource();
dbcp.setDriverClassName(PropertyUtil.getProperty("config", "other.jdbc.driver"));
dbcp.setUrl(PropertyUtil.getProperty("config", "other.jdbc.url"));
dbcp.setUsername(PropertyUtil.getProperty("config", "other.jdbc.user"));
dbcp.setPassword(PropertyUtil.getProperty("config", "other.jdbc.password"));
// 初始化
dbcp.setInitialSize(Integer.parseInt(PropertyUtil.getProperty("config", "other.initSize")));
// 最大連接數(shù)
dbcp.setMaxActive(Integer.parseInt(PropertyUtil.getProperty("config", "other.maxAtive")));
// 最大等待時間
dbcp.setMaxWait(Long.parseLong(PropertyUtil.getProperty("config", "other.maxWait")));
// 最大空閑數(shù)
dbcp.setMaxIdle(Integer.parseInt(PropertyUtil.getProperty("config", "other.maxIdle")));
// 最小空閑數(shù)
dbcp.setMinIdle(Integer.parseInt(PropertyUtil.getProperty("config", "other.minIdle")));
threadLocal = new ThreadLocal<>();
} catch (Exception e) {
log.error("DbUtil exception",e);
}
}
/**
* 獲取一個連接
* @return
*/
public static Connection getConnection() {
try {
Connection connection = dbcp.getConnection();
connection.setAutoCommit(false);
threadLocal.set(connection);
return connection;
} catch (Exception e) {
log.error("getConnection exception",e);
return null;
}
}
/**
* 歸還一個連接
*/
public static void closeConnection() {
try {
Connection connection = threadLocal.get();
if(connection != null) {
// 實際上沒有關(guān)閉連接铸本,只是放在池子里
connection.close();
threadLocal.remove();
}
} catch (Exception e) {
log.error("closeConnection exception",e);
}
}
}
- 利用junit來進(jìn)行測試
@Test
public void testDbUtil(){
String sql = "select * from study_login";
Connection connection = DbUtil.getConnection();
try{
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getInt(1));
System.out.println(resultSet.getString(2));
System.out.println(resultSet.getString(3));
}
}catch (Exception e){
logger.error("testDbUtil exception", e);
}
}
源碼
詳細(xì)代碼請參考github的DbUtil.java