前言
对于spring项目,如果需要用到多数据源,可以直接在spirng配置多个数据源,但是这种方法比较麻烦,特别是项目整合了mybatis的情况,如果我们只需要很简单地访问另外一个数据库,我们完全可以通过dbcp实现一个简单的连接池即可。
实现
一开始,我们可以用纯粹的jdbc来连接数据库,但是这样,我们每次访问数据库,都需要开启连接和关闭连接,非常浪费资源,因此,我们可以实现一个简单的连接池,用于减少这部分资源的开销。并且,我们不需要自己实现连接池的功能,各大厂商都已经为我们提供了连接池的实现,例如C3P0、DBCP连接池等,我们只需在这基础上二次开发即可,这里,我们选用DBCP来实现我们的连接池功能。
- 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类,主要是通过该类实现同步效果,防止多线程下该连接池失效。
public class DbUtil {
private static final Logger log = LoggerFactory.getLogger(DbUtil.class);
/**
* 数据库连接池
*/
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")));
// 最大连接数
dbcp.setMaxActive(Integer.parseInt(PropertyUtil.getProperty("config", "other.maxAtive")));
// 最大等待时间
dbcp.setMaxWait(Long.parseLong(PropertyUtil.getProperty("config", "other.maxWait")));
// 最大空闲数
dbcp.setMaxIdle(Integer.parseInt(PropertyUtil.getProperty("config", "other.maxIdle")));
// 最小空闲数
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) {
// 实际上没有关闭连接,只是放在池子里
connection.close();
threadLocal.remove();
}
} catch (Exception e) {
log.error("closeConnection exception",e);
}
}
}
- 利用junit来进行测试
@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);
}
}
源码
详细代码请参考github的DbUtil.java