计算机编程

java通过dbcp实现一个数据库连接池

2018-12-02  本文已影响0人  白虎先生

前言

对于spring项目,如果需要用到多数据源,可以直接在spirng配置多个数据源,但是这种方法比较麻烦,特别是项目整合了mybatis的情况,如果我们只需要很简单地访问另外一个数据库,我们完全可以通过dbcp实现一个简单的连接池即可。

实现

一开始,我们可以用纯粹的jdbc来连接数据库,但是这样,我们每次访问数据库,都需要开启连接和关闭连接,非常浪费资源,因此,我们可以实现一个简单的连接池,用于减少这部分资源的开销。并且,我们不需要自己实现连接池的功能,各大厂商都已经为我们提供了连接池的实现,例如C3P0DBCP连接池等,我们只需在这基础上二次开发即可,这里,我们选用DBCP来实现我们的连接池功能。

<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
</dependency>
#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);
        }

    }
}
@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

https://github.com/wumingzhizhu/springTest

上一篇下一篇

猜你喜欢

热点阅读