首页 > 技术文章 > Java之数据库连接池

CoLo 2021-08-05 00:19 原文

Java之数据库连接池

数据库连接池

首先,我们使用JDBC操作数据库的时候一般都会经历下面几个流程

获取数据库连接对象 ==> 执行SQL ==> 释放资源

从执行SQL到释放资源是很浪费系统资源的一个事情,所以引出了数据库连接池这么一个技术。

池化技术就是准备一些预先的资源,当有需要执行SQL时,就先使用这些预先准备的资源

编写连接池:主要实现DataSource接口即可。

开源的数据库连接池有

DBCP

C3P0

Druid: alibaba

DBCP

与之前不同的是这里需要新建一个数据库连接池,通过数据库连接池get connection对象再封装到工具类中供主函数进行调用。

像资源释放方法还是像之前的写法即可。

private static DataSource dataSource = null;

    static {

        try {
            //读取资源文件
            InputStream resourceAsStream = DbcpUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
            Properties properties = new Properties();
            properties.load(resourceAsStream);

            //创建数据源
            dataSource = BasicDataSourceFactory.createDataSource(properties);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
//获取连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

dbcpconfig.properties

#连接设置   数据源名字是jar包中设置好的,不可更改
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=password

#!-- 初始化连接 --
initialSize=10

#最大连接数量
maxActive=50

#!-- 最大空闲连接 --
maxIdle=20

#!-- 最小空闲连接 --
minIdle=5

#!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 --
maxWait=60000
#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:【属性名=property;】
#注意:user 与 password 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=UTF8

#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly=

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED

DbcpUtils

public class DbcpUtils {

    private static DataSource dataSource = null;

    static {

        try {
            //读取资源文件
            InputStream resourceAsStream = DbcpUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
            Properties properties = new Properties();
            properties.load(resourceAsStream);

            //创建数据源
            dataSource = BasicDataSourceFactory.createDataSource(properties);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //获取连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }


    //释放资源
    public static boolean closeResources(Connection connection, Statement statement, ResultSet resultSet, PreparedStatement preparedStatement){
        boolean flag = true;
        if (connection!=null){
            try {
                connection.close();
                flag = true;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }

        if (statement!=null){
            try {
                statement.close();
                flag = true;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }

        if (resultSet!=null){
            try {
                resultSet.close();
                flag = true;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }

        if (preparedStatement!=null){
            try {
                preparedStatement.close();
                flag = true;
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }

        return flag;
    }

}

TestDbcp

public class TestDBCP {

    public static void main(String[] args) {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = DbcpUtils.getConnection();
            //查询一条数据
            String sqlQ = "SELECT * FROM people where id =?";
            preparedStatement = connection.prepareStatement(sqlQ);
            preparedStatement.setInt(1,3);
            resultSet = preparedStatement.executeQuery();

            while (resultSet.next()){
                System.out.println("id = " + resultSet.getInt("id"));
                System.out.println("name = " + resultSet.getString("name"));
                System.out.println("age = " + resultSet.getInt("age"));
                System.out.println("address = " + resultSet.getString("address"));
                System.out.println("============================");
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //  释放资源
            boolean flag = JdbcUtils.closeResources(connection, preparedStatement, resultSet, null);
            if (flag){
                System.out.println("资源释放完成!");
            }else {
                System.out.println("资源释放失败!");
            }
        }

    }
}

C3P0

c3p0的配置文件可以配置多个数据库的配置。在代码中可以指定参数来制定数据源,不写参数缺省为默认的数据源配置。

ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();	//这里为缺省数据源配置
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("MySQL");		//选择MySQL为数据源配置

C3p0config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<c3p0-config>
<!--
c3p0的缺省(默认)配置
如果在代码中ComboPooledDataSource ds=new ComboPooledDataSource();这样写就表示使用的是c3p0的缺省(默认)-->
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf8&amp;uesSSL=false</property>
        <property name="user">root</property>
        <property name="password">password</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </default-config>
  
  <mysql-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf8&amp;uesSSL=false</property>
        <property name="user">root</property>
        <property name="password">password</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </mysql-config>
</c3p0-config>

其余部分可参照DBCP

推荐阅读