MySQL基础学习(六)————数据库连接池

1、什么是数据库连接池?

这个是一项池化技术,是为了提高数据库连接的使用率的一项技术。我们现在使用JDBC的时候,每次都需要和数据库新建立一个新的连接,使用完了就把这个连接关闭了,那么这样其实是很不环保的,也不利于提高程序的效率,所以就有了数据库连接池。
在这里插入图片描述

2、自己实现一个数据库连接池

/**
 * 创建自己的数据库连接池
 *
 *  带有扩容的规则 自己定义的扩容的规则
 */
public class MyConnectionPool {

    // 使用链表结构的list,规定了这个集合我们从头部添加,从尾部获取
    static LinkedList<Connection> linkedList;

    // 初始化容量大小
    static int INIT_SIZE = 10;

    // 需要扩容的大小
    static int MIN_SIZE = 5;

    // 每次扩容增加的数量
    static int INCREMENT = 10;



    static {

        linkedList = new LinkedList<>();

        // 往这个集合里面去初始化放入一些连接
        addCapacity(INIT_SIZE);

    }

    private static void addCapacity(int size) {

        for (int i = 0; i < size; i++) {
            Connection connection = JDBCUtils.getConnection();
            linkedList.addFirst(connection);
        }
    }


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

        // 如果连接池里面的连接小于临界值了,那么我们应该去给他扩容
        if (linkedList.size() < MIN_SIZE) {
            addCapacity(INCREMENT);
        }

        Connection connection = linkedList.removeLast();

        return connection;

    }



    // 返回连接
    public static void returnConnection(Connection connection){

        linkedList.addFirst(connection);
    }
}

目前为止,我们的数据库连接池还存在以下几个问题:

  1. 连接池里面没有一个连接数的上限
  2. 缺少了一套连接自动回收的机制
  3. 我们自己实现的数据库连接池没有遵循JDBC给我们提供的数据库连接池的标准

其实,JDBC给我们提供了一个数据库连接池的一个标准接口,这个接口里面定义了获取连接的方法,所以我们自己实现的连接池需要实现这个接口javax.sql.Datasource

我们发现,Datasource这个接口里面,并没有给我们定义一个 返回连接的方法,为什么没有定义呢?

是因为即使定义了返回连接的方法,也不能阻止用户先把连接关闭,然后再把连接返回给连接池。假如用户这么做了以后,我们的整个数据库连接池就废了,那么怎么样去阻止用户调用 connection.close()方法呢?

我们作为工具的设计者,没有办法阻止用户去调用connection.close()这个方法,但是我们可以去想一些别的办法。

  1. 我们的连接池里面放入的是JDBC4Connection 的子类,这个子类重写了close()方法

  2. 我们的连接池里面放入的是我们自己实现的Connection接口的实现类,这个实现类的close()方法是把连接放入到连接池

3、开源的数据库连接池

3.1 DBCP

(1)导包
commons-dbcp-1.4.jar commons-pool-1.6.jar
(2)配置一个properties

#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/31th_sql4
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=gbk;characterEncoding=utf8;useSSL=false;serverTimezone=Asia/Shanghai

#指定由连接池所创建的连接的自动提交(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

(3)使用

public class DBCPUtils {

    // 是一个连接池的接口,通常叫做数据源
    private static DataSource dataSource;

    static {

        Properties properties = new Properties();
        FileInputStream fileInputStream = null;
        try {

            fileInputStream = new FileInputStream("dbcp.properties");
            properties.load(fileInputStream);

            // 创建一个基础的数据源工厂
            BasicDataSourceFactory basicDataSourceFactory = new BasicDataSourceFactory();

            // 加载配置文件
           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;

    }
}

3.2 C3P0

(1)导包:
在这里插入图片描述
(2)在src目录下配置一个文件,这个文件的路径必须在src目录下,这个文件的名字必须是 c3p0-config.xml。

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <!--
        在xml文件里面,有一些特殊的字符是不能使用的,使用这些字符需要使用他们的转义字符
        >    gt;
        <    lt;
        &    &amp;
        -->
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/31th_sql4?characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=Asia/Shanghai&amp;rewriteBatchedStatements=true</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>


    <!--<named-config name="mysql">-->
        <!--<property name="driverClass">com.mysql.jdbc.Driver</property>-->
        <!--<property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property>-->
        <!--<property name="user">root</property>-->
        <!--<property name="password">root</property>-->

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


    <!--<named-config name="oracle">-->
        <!--<property name="driverClass">com.mysql.jdbc.Driver</property>-->
        <!--<property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property>-->
        <!--<property name="user">root</property>-->
        <!--<property name="password">root</property>-->

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

(3)使用

package com.cskaoyan.datasource.C3P0;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class C3p0Utils {

    private static DataSource dataSource;

    static {

        // 约定大于配置  方便开发者的使用
        // 给了一些约定俗成的配置,不需要修改
        dataSource = new ComboPooledDataSource();
    }


    public static Connection getConnection(){

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

        return connection;

    }
}

3.3 Druid

这个是阿里巴巴开源的一个数据库连接池,在国内因为良好的性能被广泛使用。
(1)导包:
在这里插入图片描述
(2)配置:

url=jdbc:mysql://localhost:3306/31th_sql4?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username=root
password=123456
driverClassName=com.mysql.jdbc.Driver

(3)使用:

package com.cskaoyan.datasource.Druid;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class DruidUtils {

    static DataSource dataSource;

    static {

        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("druid.properties"));

            DruidDataSourceFactory druidDataSourceFactory = new DruidDataSourceFactory();

            dataSource = druidDataSourceFactory.createDataSource(properties);


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

    public static Connection getConnection(){

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

        return connection;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值