连接池的实现:Druid实现。

目录

1.Druid下载

2.将Druid的jar包添加进工程

3.Druid连接池:初体验案例

(1)创建druid-config.properties文件

(2)编写DruidSample类

(3)总结,分析(重要!!!)

4.Druid连接池的几个点

(1)【initialSize=10】和【maxActive=20】属性设置

(2)【initialSize=10】默认连接数不够的话,会启动最大连接数【maxActive=20】属性

(3)如果程序中数据库连接数的需求超过最大连接数,那些没有分配到的程序会等待

(4)【initialSize】和【maxActive】建议设置相同值(重要!!!)

5.在实际中使用时的疑问?????(后续明确了,再回头改)


1.Druid下载

总之,在Druid的Github主页上,各种点点总能找到对应的下载链接。

maven druid连接池配置 druid连接池配置详解 maxactive_连接池

maven druid连接池配置 druid连接池配置详解 maxactive_连接池_02

https://repo1.maven.org/maven2/com/alibaba/druid/为druid的下载链接;

maven druid连接池配置 druid连接池配置详解 maxactive_配置文件_03


2.将Druid的jar包添加进工程

maven druid连接池配置 druid连接池配置详解 maxactive_数据库连接_04

然后,将Druid的jar包加入到工程依赖中;

maven druid连接池配置 druid连接池配置详解 maxactive_连接池_05

maven druid连接池配置 druid连接池配置详解 maxactive_数据库连接_06

maven druid连接池配置 druid连接池配置详解 maxactive_连接池_07

maven druid连接池配置 druid连接池配置详解 maxactive_连接池_08

这儿没有勾选,就直接点击OK了,勾选与否的区别是什么???待解答

说明:

这里的Dependencies是指这里勾选引入的依赖包可以在当前Module下使用。查看下lib目录下对应的jar包前是否有个小箭头,如果有,也是表示将该jar包添加到项目中,所以这里不勾选也是可以使用的;

maven druid连接池配置 druid连接池配置详解 maxactive_数据库连接_09

emm,个人感觉,以后是是勾选上吧。。。。


3.Druid连接池:初体验案例

(1)创建druid-config.properties文件

这个配置文件的名字可以改~~~

首先,在src下创建一个全新的properties属性文件:druid-config.properties文件。用来保存JDBC运行时必要的信息。

maven druid连接池配置 druid连接池配置详解 maxactive_配置文件_10

maven druid连接池配置 druid连接池配置详解 maxactive_数据库连接_11

然后,需要在druid-config.properties属性文件中,配置JDBC的信息;

(以前的JDBC的代码都写在了java代码中,Druid的配置为什么不也写在java代码中,而是要写在属性文件中?)Druid为了让程序程序拥有更好的可维护性;试想一下,如果将用户名、密码、连接字符串都存放到java源代码中,那么每一次更改后,都需要对源代码进行重新编译、重新部署才可以生效;;;而如果放在druid-config.properties属性文件这个配置文件中,其本身就是一个纯粹的文本文件,所以当需要修改数据库信息的时候,直接修这个文件,然后重启应用就能生效了。

在druid-config.properties属性文件配置:可配置项;

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/imooc?useSSL=false&useUincode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username=root
password=12345

JDBC的信息都放在了配置文件中,那么如何利用Druid对这些配置的信息进行加载和读取?

(2)编写DruidSample类

maven druid连接池配置 druid连接池配置详解 maxactive_maven druid连接池配置_12

DruidSample类:(1)加载属性文件;(2)获取DataSource数据源对象;(3)创建数据库连接。

package com.imooc.jdbc.sample;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.imooc.jdbc.common.DbUtils;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;

/**
 * Druid连接池配置与使用
 */
public class DruidSample {
    public static void main(String[] args) {
        //1.加载属性文件
        Properties properties = new Properties();
        //以前接触过,DruidSample.class.getResource(“某个文件”)获取当前类路径下对应文件的路径;
        String propertiesFile = DruidSample.class.getResource("/druid-config.properties").getPath();
        System.out.println("***"+propertiesFile+"***");
        try {
            // 容纳错考虑:提取的配置文件路径:base64编码转成utf-8编码;(以前遇到过)
            propertiesFile = new URLDecoder().decode(propertiesFile,"UTF-8");
            properties.load(new FileInputStream(propertiesFile));
        } catch (UnsupportedEncodingException | FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //2.获取DataSource数据源对象
        // DataSource数据源对象:java.sql提供的一个接口;利用DataSource指代我们要操作的数据库是什么;
        // DataSource也提供了获取数据库连接的方法;;;所谓数据源就是数据库在JDBC中的别称;
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            //通过DruidDataSourceFactory工厂类,创建数据源;
            DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
            //3.创建数据库连接
            conn = dataSource.getConnection();
            pstmt = conn.prepareStatement("select * from employee limit 0,10");
            rs = pstmt.executeQuery();
            while (rs.next()) {
                Integer eno = rs.getInt(1);
                String ename = rs.getString("ename");
                Float salary = rs.getFloat("salary");
                String dname = rs.getString("dname");
                System.out.println(dname + "-" + eno + "-" + ename + "-" + salary);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            /**
             * 不使用连接池:conn.close()关闭连接;
             * 使用连接池:conn.close()将连接回收至连接池;
             */
            DbUtils.closeConnection(rs,pstmt,conn);
        }

    }
}

DruidSample类几点说明:

(1)【String propertiesFile = DruidSample.class.getResource("/druid-config.properties").getPath();】DruidSample.class.getResource(“某个文件”)获取当前类路径下对应文件的路径;同时,也对获取到的路径字符串转化了编码方式;(前台系统二这篇博客中的XmlDataSource类部分有类似内容)

(2)作为Java来说,在src下,所存放的不只有程序的源代码,还有相关的配置文件,这个配置文件会随着运行一起被发布到最终的out目录下,产生在工程的运行环境中;

即编译后,所有Java类编译后的class文件都在out目录下;同样,在src中的其他配置文件也会出现在out目录中。

maven druid连接池配置 druid连接池配置详解 maxactive_数据库连接_13

(3)导入的包说明:

maven druid连接池配置 druid连接池配置详解 maxactive_数据库连接_14

maven druid连接池配置 druid连接池配置详解 maxactive_数据库连接_15

运行结果:

maven druid连接池配置 druid连接池配置详解 maxactive_maven druid连接池配置_16

(3)总结,分析(重要!!!)

发现,在使用Druid之后,好像有点无感,Druid创建的连接在哪儿?怎么没有看到?

其实可以这样理解:

          (1)在设置了配置文件(druid-config.properties)之后,启动程序之后,数据库连接池中就已经有数据库连接,这些连接池中的数据库连接等待被取用;;;

          (2)然后,在程序中,通过Properties类读取那个配置文件,然后通过Druid提供的工厂类DruidDataSourceFactory去记载读取的配置文件,就能得到DataSource数据源对象;

          (3)DataSource数据源对象可以认为是访问数据库连接池的一个对象,通过DataSource数据源可以获取数据库连接池中的连接;

在需要使用数据库的地方,就创建一个DataSource对象,然后利用DataSource对象去线程池中取一个数据库连接就好了啊。

          (4)一切就绪之后,当程序中需要数据库连接的时候,直接使用【conn = dataSource.getConnection();】从数据库连接池中去取一个连接就可以了;;;;;;而不用再使用【Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/imooc?useSSL=false&useUincode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true", "root", "12345");】去现创建数据库连接了;

          (5)即,如果没有数据库连接池的话,每当程序中需要数据库连接的时候,都是需要使用而不用再使用【Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/imooc?useSSL=false&useUincode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true", "root", "12345");】去现创建数据库连接的,这个速度就会比较慢;;;;肯定没有(4)中那样,直接去连接池中去取现成的、已经创建好的连接快啊。

maven druid连接池配置 druid连接池配置详解 maxactive_配置文件_17

maven druid连接池配置 druid连接池配置详解 maxactive_maven druid连接池配置_18


附加一个说明: 

maven druid连接池配置 druid连接池配置详解 maxactive_配置文件_19


4.Druid连接池的几个点

(1)【initialSize=10】和【maxActive=20】属性设置

maven druid连接池配置 druid连接池配置详解 maxactive_数据库连接_20

在druid-config.properties中设置两个属性:

          【initialSize=10】:连接池刚启动准备好,会默认的创建10个数据库连接;

          【maxActive=20】:如果在实际项目运行中,10个连接不够用,连接池会额外的再创建新的数据库连接,但总数不得超过20;

           如果在程序运行中,连接池创建的连接已经达到了上限,连接还不够用的话,那些没有分到数据库连接的程序就会一直进入等待的状态,等待其他正在使用连接池中连接的程序调用close()方法,然后连接池就会将数据库连接进行回收,然后那些苦苦等待的程序就会有数据库连接可用,然后去执行了。

maven druid连接池配置 druid连接池配置详解 maxactive_maven druid连接池配置_21

通过Navicat工具的【服务器监控】界面中可以看到目前所有已创建的数据库连接:

maven druid连接池配置 druid连接池配置详解 maxactive_连接池_22

maven druid连接池配置 druid连接池配置详解 maxactive_数据库连接_23

maven druid连接池配置 druid连接池配置详解 maxactive_配置文件_24

……………………………………………………

(2)【initialSize=10】默认连接数不够的话,会启动最大连接数【maxActive=20】属性

maven druid连接池配置 druid连接池配置详解 maxactive_配置文件_25

可以发现,初始的数量不够用了,连接池会自动的帮我们扩展新的连接,直到达到允许的上限; 

maven druid连接池配置 druid连接池配置详解 maxactive_数据库连接_26

……………………………………………………

(3)如果程序中数据库连接数的需求超过最大连接数,那些没有分配到的程序会等待

如:

maven druid连接池配置 druid连接池配置详解 maxactive_maven druid连接池配置_27

maven druid连接池配置 druid连接池配置详解 maxactive_连接池_28

maven druid连接池配置 druid连接池配置详解 maxactive_数据库连接_29

这也是在实际中使用数据库连接池时需要注意的点。在实际中,一旦程序达到生产的服务器上,运行一段时间后,程序就无缘无故的被卡死,这很有可能是数据库连接池的最大数量设置的不够了,从而让程序一直处于等待的状态。

那么连接池最大数量设置多少合适?需要根据实际项目的情况来决定,比如通常1个用户使用1个数据库连接,那么就要测算在最忙碌的时候,同时会有多少个用户来使用我们的系统。最大的连接数量一定要超过最大的用户数,才能保证程序不会因为这个问题而阻塞。

……………………………………………………

(4)【initialSize】和【maxActive】建议设置相同值(重要!!!)

一个比较不错的技巧,也是很多资深开发者的做法:将初始的数量(【initialSize】)和最大的数量(【maxActive】)把持一致;比如【initialSiz=20】,【maxActive=20】,都设置成20;

这是因为:在日常工作中,应用程序最好在一开始就把所有的连接和资源都分配好,用户进来了以后直接获取现成的资源,避免出现重新创建资源的情况;这样对于整体的程序管理和性能都是有帮助的。


5.在实际中使用时的疑问?????(后续明确了,再回头改)

*************************************************************************************************

首先有两个前提:

前提1:Druid连接池连接池的初始化需要使用Druid的配置文件;

前提2:在工程启动的时候,需要初始化连接池;

maven druid连接池配置 druid连接池配置详解 maxactive_配置文件_30

maven druid连接池配置 druid连接池配置详解 maxactive_maven druid连接池配置_31

三个疑问:

疑问1:加载属性文件得到Properties对象的初始化代码放在哪儿?(这些初始化代码肯定是在工程启动的时候就要执行啊,这样才能提前准备好Druid连接池);是不是把这些工作放在那些工程启动时会默认先执行的代码中?

疑问2:Properties对象是做成一个全局可访问的变量吗?

疑问3:数据源对象DateSource对象,是在哪儿创建的?是和Properties对象的初始化代码放在一起,做成全局变量;还是在需要使用数据库连接的地方,再现创建?换句话说,在整个项目中,是只有一个DateSource对象,还是有多个DataSource对象?

Answer:

1、不可以更改名字

2、new Properties()这个操作就是在得到properties对象

3、Properties对象是做成一个全局可访问的变量吗?

这里创建Properties对象是为了加载配置文件,没有必要定义成全局可以访问的变量

3、1)通过DruidDataSourceFactory工程类的createDataSource()方法在底层创建DataSource数据源

maven druid连接池配置 druid连接池配置详解 maxactive_配置文件_32

2)用到时再创建即可

3)是可以有多个DataSource对象的

*************************************************************************************************

目前我的理解,在实际使用中。使用了Druid以后,工程启动之后,那些数据库连接就已经存在了。然后在需要使用数据库连接的时候,通过上面的步骤,直接去获取连接就好了。