【归纳总结】数据库之连接池

我们用 JDBC 操作数据库的时候,每次操作完都会将连接关闭。数据库连接是极其宝贵的资源,频繁的创建和销毁会极大地降低服务器的性能。因此,我们可以利用池化技术,重复利用数据库资源,避免没必要的开销。

用口语来说,相当于我们创建了一个池子,这个池子里面放的都是一些JDBC的连接,也就是Connection对象,每当我们需要时,我们去从连接池里面获取连接,使用完了连接,放回连接池,做到连接的反复使用

手写一个数据库连接池

思路:

  1. 要实现DataSource接口(SUN公司就制定的连接池的标准)
  2. 要有一个getConnection()方法用来获取连接池中的connection对象
  3. 连接池中的connection对象有进有出,所以把他们放入队列使用起来是比较方便的
  4. 当connection对象调用close()方法的时候不应该关闭连接池,而是要把连接放回连接池中,所以我们要自建一个连接对象(通过实现connection接口)

伪代码如下:
重写close():

public class MyWrapperConnection implements Connection{
    
    
    // 维护一个Connection对象,重写除close()以外的方法我们直接用Connection对象的方法
    private Connection connection;
    // 维护一个队列用来
    private LinkedList<Connection> queue;

    // 无参构造
    public MyWrapperConnection() {
    
    
    }

    // 有参构造
    public MyWrapperConnection(Connection connection, LinkedList<Connection> linkedList) {
    
    
        this.connection = connection;
        this.linkedList = linkedList;
    }

    //重写close()方法
    @Override
    public void close() throws SQLException {
    
    
        // 用完放回队列
        queue.offer(this);
    }

构建连接池:

public class MyConnectionPool implements DataSource {
    
    

    // 得用一个数据结构去存放连接
    static LinkedList<Connection> queue;

    static {
    
    

        init(10);

    }
    // 往连接池里面放连接的方法
    private static void init(int num) {
    
    
        if (connectionPool == null) {
    
    
            connectionPool = new LinkedList<>();
        }
        for (int i = 0; i < num; i++) {
    
    
            // 添加一个连接
            Connection connection = JDBCUtils.getConnection();
            MyWrapperConnection myWrapperConnection = new MyWrapperConnection(connection, queue);
            connectionPool.addFirst(myWrapperConnection);
        }
    }

    @Override
    public Connection getConnection() throws SQLException {
    
    
        return queue.pull();
    }

总结:我们发现自己手动实现这一系列连接池比较麻烦,并且很多功能自己都没有去实现,所以网上有很多第三方的开源的数据库连接池供我们使用,如DBCP、C3p0、Druid

开源的数据库连接池

1️⃣DBCP

第一步,导包
<!--DBCP-->
<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
</dependency>

<dependency>
    <groupId>commons-pool</groupId>
    <artifactId>commons-pool</artifactId>
    <version>1.6</version>
</dependency>
第二步,配置

dbcp.properties文件中进行如下配置:

#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/28_jdbc
username=root
password=123456
#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

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

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

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

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

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

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

创建一个工具类用来获取连接

public class DBCPUtils {
    
    

    // 声明一个数据源对象
    private static DataSource dataSource;

    static {
    
    

        // 加载配置文件
        Properties properties = new Properties();
        ClassLoader classLoader = DBCPUtils.class.getClassLoader();
        InputStream stream = classLoader.getResourceAsStream("dbcp.properties");
        try {
    
    
            properties.load(stream);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
		// 涉及到了一个设计模式:工厂模式(后面会讲)
        // 创建一个数据源工厂对象
        BasicDataSourceFactory basicDataSourceFactory = new BasicDataSourceFactory();

        try {
    
    
            // 给Datasource赋值
            dataSource = basicDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }

    }

    // 写一个方法 获取连接
    public static Connection getConnection(){
    
    
        Connection connection = null;
        try {
    
    
            connection = dataSource.getConnection();
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        }
        return connection;
    }

2️⃣C3p0

第一步,导包
<!--c3p0-->
<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.4</version>
</dependency>
第二步,配置

在c3p0-config中进行如下配置:

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/28_jdbc</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </default-config>
</c3p0-config>
第三步,创建C3p0Utils对象

创建一个工具类用来获取连接

public class C3p0Utils {
    
    

    // 首先声明一个数据源对象
    private static DataSource dataSource;

    static {
    
    

        // 给Datasource对象去赋值
        dataSource = new ComboPooledDataSource();
    }

    // 获取连接
    public static Connection getConnection(){
    
    

        Connection connection = null;
        try {
    
    
            connection = dataSource.getConnection();
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        }
        return connection;

    }
}

3️⃣Druid(最重要!!!)

第一步,导包
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.19</version>
</dependency>
第二步,配置

在druid.properties文件中进行如下配置

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db1
username=root
password=123456
第三步,创建DruidUtils对象

创建一个工具类用来获取连接

public class DruidUtils {
    
    

    private static DataSource dataSource;

    static {
    
    
        // 加载配置文件
        Properties properties = new Properties();
        ClassLoader classLoader = DruidUtils.class.getClassLoader();
        InputStream stream = classLoader.getResourceAsStream("druid.properties");

        try {
    
    
            properties.load(stream);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }

        // 创建一个Druid数据源工厂对象
        DruidDataSourceFactory dataSourceFactory = new DruidDataSourceFactory();
        try {
    
    
            // 通过工厂创建一个数据源并且去赋值
            dataSource = dataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }

    }
    // 获取连接
    public static Connection getConnection(){
    
    

        Connection connection = null;
        try {
    
    
            connection = dataSource.getConnection();
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        }
        return connection;

    }

}

猜你喜欢

转载自blog.csdn.net/Octavius_/article/details/114854569