200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > c3p0 DBCP Druid(德鲁伊)数据库连接池

c3p0 DBCP Druid(德鲁伊)数据库连接池

时间:2024-07-12 21:55:08

相关推荐

c3p0 DBCP Druid(德鲁伊)数据库连接池

c3p0,DBCP,Druid(德鲁伊)数据库连接池

每博一文案

佛说:前世 500 次的回眸,才换来今生的一次擦肩而过。人与人之间的缘分,真的无需强求,并不是所有的感情都能天长地久,正如《越过山丘》里唱的:总有人幸福白头,总有人哭着分手,无论相遇还是不相遇,都是献给岁月的序曲人生。这场长途跋涉的旅程中,有花繁盛开的世外桃源,也有遍地荒芜的戈壁沙漠,有注定的失去,也有没有结果的相遇,遇见谁发生怎样的故事,大体都是缘分,有时候,有些事不用开口也明白。有时候,有些路不走也会变长,在一起的时候,就用力爱,不留遗憾。如果无法继续携手前行,缘分到头的时候,就痛快的说一声再见,他们只是你人生的过客,在你的生活当中,陪你做过一段路,共同经历一些风景,然后经过时间的节点,在某个不经意间,又演了一场离别,是一场结束,却是一场开始,放手才能感受解脱,失去了才懂得珍惜,我们要悄然收起过往的心酸,继续自己的人生。有些人走进你的生命,只是为了证明你们没有缘分,不需说再见。愿你得到而不喜,失而不忧。所有失去的,都会以另一种方式归来。—————— 一禅心灵庙语

文章目录

c3p0,DBCP,Druid(德鲁伊)数据库连接池每博一文案1. JDBC数据库连接池的必要性1.2 JDBC 连接数据库2. 数据库连接池技术2.1 数据库连接池技术的优点3. 多种开源的数据库连接池4. C3P0数据库连接池5. DBCP数据库连接池6. Druid(德鲁伊)数据库连接池7. 总结:8. 最后:

1. JDBC数据库连接池的必要性

在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤执行的

在主程序 (如 servlet,beans) 中建立数据库连接执行相关的 sql语句操作数据库使用完后关闭数据库连接

如下图示:

传统方式的连接数据库,存在的问题:

普通的JDBC数据库连接使用DriverManager来获取到连接的,每次向数据库请求建立连接的时候,都要将 Connection 加载到内存中,再验证用户名和密码(需要花费0.05s ~ 1s的时间) 。需要数据库连接的时候,就向数据库要求一个,执行完成后再断开连接,这样的方式,将会消耗大量的资源和时间。数据库的连接资源并没有得到一个很好的重复利用,如果同时有几百人甚至 几千人在线,频繁的进行数据库连接操作将占用很多的系统资源,严重的甚至会造成服务器的崩溃。本博客后面会作相应的演示,请大家继续往后看下去。对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将导致重启数据库。何为Java的内存泄漏这种开发不能控制被创建的连接对象数,不能很好的管理连接的资源信息,系统资源会被毫无顾忌的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。

1.2 JDBC 连接数据库

这里我们演示使用传统的数据库连接池,将向 Mysql数据库请求 5000 次的连接,看看会发生什么事情 ???

包如下错误:java.sql.SQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"

package Blogs.blogs04;import java.io.IOException;import java.io.InputStream;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.util.Properties;public class JDBCTest {public static void main(String[] args) {// 读取配置文件信息InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"); // 默认读取的是src目录下的文件try {Properties properties = new Properties(); // 创建读取.properties后缀的配置文件的对象properties.load(is); // 以简单的线性格式输入字符读取属性列表(关键字/元素对)// 通过对象传入关键字获取到其中的信息String driverClass = properties.getProperty("driverClass");String url = properties.getProperty("url");String user = properties.getProperty("user");String password = properties.getProperty("password");// 3. 加载/注册驱动Class.forName(driverClass);// 测试连接 5000 次for(int i = 0; i < 5000; i ++) {// 连接数据库Connection connection = DriverManager.getConnection(url,user,password);}} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}}}

2. 数据库连接池技术

为此,为了解决传统开发中的数据库连接问题,基本上也就是上述提到的三个问题,可以采用数据库连接池技术

数据库连接池的基本思想:就是为数据库连接建立了一个 “连接池/缓冲池”。预先在连接池/缓冲池中放入一定数量的已经连接上数据库的连接对象,当我们需要建立数据库连接时,只需要从 “连接池/缓冲池”中取出一个,使用完毕之后再 “归还给数据库了连接池”数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。大大提高了连接数据库的效率数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数设定的(可以自行设定其最小连接数)。无论这些存放在数据库连接池中的连接是否被使用上,连接池都将一直保证至少含有这么多的连接数量,数据库连接池的最多数据库连接数量限定了这个连接池能占有的最大连接数,如果数据库连接池设定的最多连接数量都被占用了,这时候,当应用程序向数据库连接池请求连接时。这些连接请求将会加入到等待队列中,如果到达一定时间,还没有获取到连接,就会丢弃该连接请求。 如下图示:

工作原理:

这里我们使用一个生动形象的例子来说明传统 JDBC 数据库连接,与使用数据库连接池的连接:

比如我们要从上海 ——> 北京的天安门:

传统的 JDBC 数据库连接是,我们自己手动的制造出一台汽车,然后开着这台我们自己制造的汽车,前往北京的天安门,到达天安门以后,我们就将汽车销毁了。到我们返回 上海的时候,再造一台汽车返回上海,到达上海后又将其销毁了。别人都不可以用。数据库连接池是:我们乘坐直达的公共汽车到达北京的天安门,然后下车,公共汽车不销毁,可以继续载其他的人,当我们返回上海是,继续乘坐公共汽车,到达上海,同样公共汽车不销毁,可以继续乘载其他人。减少了资源的浪费。可以不断的重复利用。

2.1 数据库连接池技术的优点

资源重用

由于数据库连接得以重用,避免了频繁创建,释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增加了系统运行环境的平稳性.

更快的系统反应速度

数据库连接池在初始化过程中,往往已经创建了若干个数据库连接存放于连接池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用的连接,避免了数据库连接初始化和释放过程的时间开销,从而减少了系统的响应时间。

新的资源分配手段

对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接池的配置,实现某一应用最大可用数据库连接数的限制,避免某一应用独占所有的数据库资源。

统一的连接管理,避免数据库连接泄漏

在较为完善的数据库连接池实现中,可根据预先的占用超时设定,强制回收被占用的连接,从而避免了常规数据库连接操作中可能出现的资源的泄漏问题。

3. 多种开源的数据库连接池

JDBC的数据库连接池使用javax.sql.DataSource来表示,DataSource只是一个接口,该接口通常由服务器(Weblogic,WebSphere,Tomcat) 提供实现,也有一些开源组织提供实现了:如下

DBCP是Apache 提供的数据库连接池。tomcat服务器自带dbcp数据库连接池,速度比c3p0较快,但因自身存在 BUG,Hibernate3 已不再提供支持了C3P0是一个开源组织提供的一个数据库连接池,速度相对较慢,稳定性还可以,Hibernate 官方推荐使用Proxoolsourceforge下的一个开源项目数据库连接池,有监控连接状态的功能,稳定性较C3P0差一点。BoneCP是一个开源组织提供的数据库连接池,速度快Druid是阿里提供的数据库连接池,据说集DBCP,C3P0,Proxool优点于一身的数据库连接池,但是速度不确定是否有BoneCP快。市面上大多都是使用 该数据库连接池

DataSource通常被称为数据源,是在javax.sql.DataSource包下的一个接口。它包含连接池和管理连接池两部分,习惯上也经常把 DataSource 称为连接池

DataSource用来取代DriverManager来获取Connection连接,获取速度快,同时可以大幅度提高数据库访问速度。

特别注意:

DataSource数据源(数据库连接池)和数据库连接不同,数据库连接池不需要创建多个,我们可以把它比作是生产数据库连接的工厂,当我们的连接数量不够时,可以通过配置增加数据库连接池中的存储的连接,因此整个应用只需要一个数据库连接池(数据源)即可。创建过多的数据库连接池,反而会适得其反。当访问数据库,操作数据库结束后,程序还是像以前一样关闭数据连接:connection.close(),不过使用数据库连接池不同的是,这里仅仅是把数据库连接归还数据库连接池,并不是真正关闭对数据库的连接。这个连接还在。

虽然它们使用都是Connection.close()方法,但是所在的包路径是不同的,因为实现方式是不同的。在’com.mysql.cj.jdbc.ConnectionImpl’包中的是真正的关闭与数据库的连接,而在``包下是归还连接给数据库连接池。

javax.sql.DataSource包下的DataSource接口的文档:

4. C3P0数据库连接池

C3P0是第三方的封装的数据库连接池,所以我们需要导入相关的c3p0-0.9.1.2-jdk1.3.jar包才可以使用:如下

相关的jar文件,我已经提交到Github,Gitee当中的了,如有需要的可以自行获取。

Mysql数据库驱动/数据库连接池驱动 · 彩虹海/软件和配置 - 码云 - 开源中国 ()software-and-configuration/Mysql数据库驱动/数据库连接池驱动 at master · China-Rainbow-sea/software-and-configuration ()

这里我使用的是IDEA编辑器,下面为我们的项目中导入c3p0-0.9.1.2-jdk1.3.jar包,操作如下:

这里就导入jar包成功了,后面的 DBCP,Druid 同样也是需要这样导入相关的jar包也是这样操作。

获取c3p0数据库连接池中的连接的方式一:通过传入相关配置参数,先创建 c3p0 数据库连接池,再从创建的 c3p0 数据库连接池中获取其中的连接。这种方式不推荐

至于如何创建 c3p0 数据库连接池以及 获取其中的连接,我们可以打开我们下载到的c3p0文档中路径为 c3p0\c3p0-0.9.1.2 下找了一个名为index.html的帮助文档,打开它,里面有相关的 c3p0 的使用

打开显示如下效果:

import com.mchange.v2.c3p0.*;...ComboPooledDataSource cpds = new ComboPooledDataSource();cpds.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver cpds.setJdbcUrl( "jdbc:postgresql://localhost/testdb" );cpds.setUser("dbuser"); cpds.setPassword("dbpassword");

我们按照上面的创建 c3p0 的案例演示,创建 c3p0 数据库连接池并获取其中连接池中的连接

package Blogs.blogs04;import com.mchange.boPooledDataSource;import java.beans.PropertyVetoException;import java.sql.Connection;import java.sql.SQLException;public class C3P0Test {public static void main(String[] args) {try {// 通过传入配置参数,创建 c3p0 数据库连接池ComboPooledDataSource cpds = new ComboPooledDataSource();cpds.setDriverClass( "com.mysql.cj.jdbc.Driver" ); // 注册数据库驱动信息cpds.setJdbcUrl( "jdbc:mysql://localhost:3306/test"); // 实际连接的数据库的url在网络中所在的位置cpds.setUser("root"); // 用户名cpds.setPassword("MySQL123"); // 密码// 从c3p0 数据库连接池中获取连接数据库的对象Connection connection = cpds.getConnection();System.out.println(connection); // 打印连接的地址System.out.println(connection.getClass()); // 打印显示实现该类的所在包路径} catch (PropertyVetoException e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出} catch (SQLException e) {throw new RuntimeException(e);}}}

使用C3P0数据库连接池的配置文件方式,获取数据库的连接方式二:推荐

关于如何编写c3p0的配置文件,同样查看其index.html的文档,如下:

<c3p0-config><default-config><property name="automaticTestTable">con_test</property><property name="checkoutTimeout">30000</property><property name="idleConnectionTestPeriod">30</property><property name="initialPoolSize">10</property><property name="maxIdleTime">30</property><property name="maxPoolSize">100</property><property name="minPoolSize">10</property><property name="maxStatements">200</property><user-overrides user="test-user"><property name="maxPoolSize">10</property><property name="minPoolSize">1</property><property name="maxStatements">0</property></user-overrides></default-config><!-- This app is massive! --><named-config name="intergalactoApp"> <property name="acquireIncrement">50</property><property name="initialPoolSize">100</property><property name="minPoolSize">50</property><property name="maxPoolSize">1000</property><!-- intergalactoApp adopts a different approach to configuring statement caching --><property name="maxStatements">0</property> <property name="maxStatementsPerConnection">5</property><!-- he's important, but there's only one of him --><user-overrides user="master-of-the-universe"> <property name="acquireIncrement">1</property><property name="initialPoolSize">1</property><property name="minPoolSize">1</property><property name="maxPoolSize">5</property><property name="maxStatementsPerConnection">50</property></user-overrides></named-config></c3p0-config>

需要注意的是:c3p0 的配置文件名是:c3p0-config.xml是不可以修改的,默认使用的就是这个文件名.

我们使用的是IDEA编译器,下面是如果在 IDEA 中创建xml文件,有的 IDEA 中 new 没有 xml,这时候就需要我们自己手动配置了。具体操作如下:

接下来就是仿照上面index.html中 c3p0-config.xml 配置文件案例编写配置文件信息了。具体的编写的配置信息如下,大家可以直接复制粘贴上去,就可以直接使用了。不对,大家还要手动修改一下你所对应的 user用户名和 password 密码,以及 url 实际数据库的网络位置。其他的到没有什么问题了。

<?xml version="1.0" encoding="UTF-8"?> <!-- 这句不要动,表示xml的版本,以及读取的编码--><c3p0-config><named-config name="helloc3p0"> <!-- 表示创建c3p0数据库连接池时,查询的文件名来源,可以手动修改;--><!-- 获取连接的4个基本信息 --><property name="user">root</property><property name="password">MySQL123</property><property name="jdbcUrl">jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true</property><property name="driverClass">com.mysql.cj.jdbc.Driver</property><!-- 涉及到数据库连接池的管理的相关属性的设置 --><!-- 若数据库中连接数不足时, 一次向数据库服务器申请多少个连接 --><property name="acquireIncrement">5</property><!-- 初始化数据库连接池时连接的数量 --><property name="initialPoolSize">5</property><!-- 数据库连接池中的最小的数据库连接数,注意初始化连接个数与最小连接个数不要出现冲突 --><property name="minPoolSize">5</property><!-- 数据库连接池中的最大的数据库连接数 --><property name="maxPoolSize">10</property><!-- C3P0 数据库连接池可以维护的 Statement 的个数 --><property name="maxStatements">20</property><!-- 每个连接同时可以使用的 Statement 对象的个数 --><property name="maxStatementsPerConnection">5</property></named-config></c3p0-config>

我们编写好相关的c3p0-config.xml配置文件以后,就可以通过访问配置文件中的信息,创建c3p0数据库连接池,以及获取其中的连接了。

具体代码实现如下:

import com.mchange.boPooledDataSource;import javax.sql.DataSource;import java.beans.PropertyVetoException;import java.sql.Connection;import java.sql.SQLException;public class C3P0Test {// 方式二: 通过读取配置文件中的信息,创建c3p0数据库连接池public static void main(String[] args) {// 创建c3p0数据库连接池DataSource dataSource = new ComboPooledDataSource("helloc3p0");try {// 获取到数据库连接池中的连接Connection connection = dataSource.getConnection();System.out.println(connection); // 打印连接地址System.out.println(connection.getClass()); // 打印类所在包下的路径} catch (SQLException e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出}}}

对 c3p0 数据库连接池进行一个封装,封装到JDBCUtils类当中。

错误演示:

package Blogs.blogs04;import com.mchange.boPooledDataSource;import java.sql.Connection;import java.sql.SQLException;public class JDBCUtils {public static Connection getConnection() {// 通过 c3p0-config.xml 配置文件,创建c3p0数据库连接池ComboPooledDataSource cpds = new ComboPooledDataSource("helloc3p0");Connection connection = null;try {connection = cpds.getConnection();} catch (SQLException e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出}return connection;}}

错误原因:

我们把创建c3p0数据库连接池放到了,调用返回连接中了。

把创建c3p0数据库连接池定义在方法中的后果是:我们每次调用该方法获取连接池,都会创建一个新的 c3p0 数据库连接池,一个连接池的创建的消耗远远比创建一个连接消耗来的大,而我们这么做就是:每创建一个连接就需要创建一个数据库连接池,还不如不用数据库连接池呢。

所以注意:一个应用使用一个数据库连接池就足够了,需要连接时,从数据库连接池中获取,如果数据库连接池中的连接不够了,可以通过配置增加数据库连接池中存有的连接,就把数据库连接池比作是一个生产连接的工厂。

综上所述:我们只要一个数据库连接池,所以我们可以将创建 c3p0 数据库连接池定义成静态 static 的类属性,和类一起加载到内存当中,只定义一次,所有对象共用这个数据库连接池

修改代码如下:

package Blogs.blogs04;import com.mchange.boPooledDataSource;import java.sql.Connection;import java.sql.SQLException;public class JDBCUtils {// 通过 c3p0-config.xml 配置文件,创建c3p0数据库连接池private static ComboPooledDataSource cpds = new ComboPooledDataSource("helloc3p0"); // 作为类属性存在public static Connection getC3p0Connection() {Connection connection = null;try {connection = cpds.getConnection(); // static 静态不要使用 this的引用} catch (SQLException e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出}return connection;}}

比较传统的 JDBC 连接数据库,和 C3P0 使用数据连接池的性能

jdbc 与 c3p0 都与数据库连接 5000 次,比较连接完后所消耗的时间:

传统的 JDBC 连接数据库 5000 次

package Blogs.blogs04;import java.io.IOException;import java.io.InputStream;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.util.Properties;public class JDBCTest {public static void main(String[] args) {// 读取配置文件信息InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"); // 默认读取的是src目录下的文件try {Properties properties = new Properties(); // 创建读取.properties后缀的配置文件的对象properties.load(is); // 以简单的线性格式输入字符读取属性列表(关键字/元素对)// 通过对象传入关键字获取到其中的信息String driverClass = properties.getProperty("driverClass");String url = properties.getProperty("url");String user = properties.getProperty("user");String password = properties.getProperty("password");// 3. 加载/注册驱动Class.forName(driverClass);long start = System.currentTimeMillis(); // 获取到 5000 次连接数据库的前的时间点:单位:毫秒// 测试连接 5000 次for(int i = 0; i < 5000; i ++) {// 连接数据库Connection connection = DriverManager.getConnection(url,user,password);if(connection != null) {try {connection.close(); // 关闭数据库连接} catch(SQLException e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出}}}long end = System.currentTimeMillis(); // 5000次连接数据库结束的时间点:单位:毫秒System.out.println("jdbc 5000 次连接数据库所消耗的时间:" + (end - start));} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}}}

C3P0 数据库连接池 中获取 5000 次的连接所消耗的时间

import com.mchange.boPooledDataSource;import javax.sql.DataSource;import java.beans.PropertyVetoException;import java.sql.Connection;import java.sql.SQLException;public class C3P0Test {// 方式二: 通过读取配置文件中的信息,创建c3p0数据库连接池public static void main(String[] args) {// 创建c3p0数据库连接池DataSource dataSource = new ComboPooledDataSource("helloc3p0");long start = System.currentTimeMillis(); // 连接前的时间点:单位:毫秒try {for(int i = 0 ; i < 5000; i++) {// 获取到数据库连接池中的连接Connection connection = dataSource.getConnection();if(connection != null) {try{connection.close(); // 使用使用数据库连接池,归还连接,不是关闭连接} catch(SQLException e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出}}}long end = System.currentTimeMillis(); // 连接结束后的时间点: 单位:毫秒System.out.println("c3p0 数据库连接池 5000 次连接所消耗的时间:"+ (end - start));} catch (SQLException e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出}}}

使用 c3p0 我们再将连接次数 增加到 5W, 50W 查看所消耗的时间:

我们可以看到非常明显的性能差,c3p0 比传统的 jdbc 连接快了 100 多倍,这就是我们使用数据库连接池的原因之一。

5. DBCP数据库连接池

DBCP是 Apache 软件基金组织下的开源连接池实现,该连接池依赖该组织下的另一个开源系统:Common-pool。如需要使用DBCP数据库连接池,则需要导入如下两个jar文件:

Commons-dbcp.jar连接池的实现架包Commons-pool.jar连接池实现的依赖库。 同样我们也将相应的jar包托放到 Github ,Gitee 当中了 Mysql数据库驱动/数据库连接池驱动 · 彩虹海/软件和配置 - 码云 - 开源中国 ()software-and-configuration/Mysql数据库驱动/数据库连接池驱动 at master · China-Rainbow-sea/software-and-configuration ()

Tomcat 的连接池正是采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。

数据源(数据库连接池)和数据库连接不同,数据库连接池无需创建多个,它是产生数据库连接的工厂,因此整个应用只需要一个数据库连接池即可

方式一: 使用传参数的方式创建 DBCP 数据库连接池,在获取连接,不推荐

关于如何创建DBCP数据库连接池,同样我们可以阅读其中的index.html帮助文档:在我们所下 jar包文件的路径下:Commons-dbcp\commons-dbcp-1.4\apidocs

导入 Commons-dbcp.jar,Commons-pool.jar 两个jar

具体代码实现如下:

package Blogs.blogs04;import mons.dbcp.BasicDataSource;import java.sql.Connection;import java.sql.SQLException;public class DBCPTest {public static void main(String[] args) {// 定义创建 dbcp 数据库连接池的对象BasicDataSource source = new BasicDataSource();source.setDriverClassName("com.mysql.cj.jdbc.Driver"); // 注册驱动这里是mysql8.0/ 5.0的没有 cjsource.setUrl("jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true"); // 实际数据库在网络url的位置// ?rewriteBatchedStatements=true批量处理// 或者可以省略本地主机 localhost:3306 改为 jdbc:mysql:///testsource.setUsername("root"); // 用户名source.setPassword("MySQL123"); // 密码// 获取到数据库中的连接try {Connection connection = source.getConnection();System.out.println(connection); // 所获得的连接的地址System.out.println(connection.getClass()); // 类所在的包路径} catch (SQLException e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出}}}

方式二:将所需的参数编写到配置文件当中,配置文件是以.properties为后缀的文件

注意是该配置文件创建在src目录下,这里我们将我们的 dbcp 所编写的配置文件名为为dbcp.properties

IDEA 中的 src 目录中创建.properties文件

该文件的编写如下:

driverClassName=com.mysql.cj.jdbc.Driverurl=jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true# ?rewriteBatchedStatements=true 表示批量处理username=rootpassword=MySQL123# 不要加空格和分号,不然报错,空格也会被当作是参数变量,识别使用

其他的配置文件的参数如下:大家可以自行参考,斟酌添加上

具体代码实现如下:

import java.io.InputStream;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;public class DBCPTest {// 方式二:通过读取配置文件中的信息,创建dbcp数据库连接池public static void main(String[] args) {try {// 读取配置文件中的信息,方式一:FileInputStream is = new FileInputStream(new File("src/dbcp.properties"));// 读取配置文件中信息,方式二:InputStream io = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties"); // 默认是读取src目录下的文件// 创建对象获取读取到的配置文件的参数信息Properties properties = new Properties();properties.load(is); // 以简单的线性格式输入字符读取到属性列表(关键字/元素对)// 通过传入获取配置文件的对象,创建dbcp 数据库连接池DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);// 从dbcp 数据库连接池中获取到连接Connection connection = dataSource.getConnection();System.out.println(connection); // 显示连接地址System.out.println(connection.getClass()); // 显示类所在的包下的路径} catch (Exception e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出}}}

下面我们对 dbcp 数据库连接池进行一个封装,如下:同样注意,一个应用一个数据库连接池就足够了。

错误演示:

我们需要调用方法读取配置文件中的信息,定义对象在类当中:作为类属性存在没有问题,但是在类当中我们是无法调用方法的。

方法的调用需要是在:代码块当中:方法中的代码块,以及 类当中的 static 静态代码块,而静态代码块的特点十分符合我们一个应用一个 数据库连接池,因为 static 静态代码块(和类一起加载到内存当中,仅仅执行一次,所有对象共用它)。

改正:

具体代码如下:

import com.mchange.boPooledDataSource;import mons.dbcp.BasicDataSourceFactory;import javax.sql.DataSource;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;public class JDBCUtils {private static DataSource dataSource = null;static {try {// 读取配置文件中的信息,方式一:FileInputStream is = new FileInputStream(new File("src/dbcp.properties"));// 读取配置文件中信息,方式二:InputStream io = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties"); // 默认是读取src目录下的文件// 创建对象获取读取到的配置文件的参数信息Properties properties = new Properties();properties.load(is); // 以简单的线性格式输入字符读取到属性列表(关键字/元素对)// 通过传入获取配置文件的对象,创建dbcp 数据库连接池dataSource = BasicDataSourceFactory.createDataSource(properties);} catch (Exception e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出}}public static Connection getDbcpConnection() {try {Connection connection = dataSource.getConnection();return connection;} catch (SQLException e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出}}}

测试 DBCP 数据库连接池处理 5000次/5w次50w次 连接所消耗的时间:

具体代码如下:

import mons.dbcp.BasicDataSource;import mons.dbcp.BasicDataSourceFactory;import javax.sql.DataSource;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;public class DBCPTest {// 方式二:通过读取配置文件中的信息,创建dbcp数据库连接池public static void main(String[] args) {try {// 读取配置文件中的信息,方式一:FileInputStream is = new FileInputStream(new File("src/dbcp.properties"));// 读取配置文件中信息,方式二:InputStream io = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties"); // 默认是读取src目录下的文件// 创建对象获取读取到的配置文件的参数信息Properties properties = new Properties();properties.load(is); // 以简单的线性格式输入字符读取到属性列表(关键字/元素对)// 通过传入获取配置文件的对象,创建dbcp 数据库连接池DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);long start = System.currentTimeMillis(); // 获取到连接前的时间点: 单位毫秒for(int i = 0; i < 5000; i++) {// 从dbcp数据库连接池中获取到连接Connection connection = dataSource.getConnection();if(connection != null) {try{// 归还连接,不是关闭连接connection.close();} catch(SQLException e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出}}}long end = System.currentTimeMillis(); // 获取到所有连接完毕后的时间点:System.out.println("5000次连接所消耗的时间: " + (end - start));} catch (Exception e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出}}}

6. Druid(德鲁伊)数据库连接池

Druild是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0,DBCP,ProxoolDB池的优点,同时加入了日志监控,可以很好的监控数据库连接池SQL的执行情况,可以说针对监控而生的 数据库连接池,同时也可以说是目前最好的连接池之一。是目前市场上大部分厂家使用的数据库连接池(数据源)。 同样的 Druid 也有相关的index.html帮助文档:在如下路径中 commons-dbutils-1.3\apidocs

和上面的两个数据库连接池是一样的,同样需要导入 有关Druild的 jar 包commons-dbutils-1.3.jar如下

IDEA 导入 commons-dbutils-1.3.jar 包

同样我们也将相应的jar包托放到 Github ,Gitee 当中了

Mysql数据库驱动/数据库连接池驱动 · 彩虹海/软件和配置 - 码云 - 开源中国 ()software-and-configuration/Mysql数据库驱动/数据库连接池驱动 at master · China-Rainbow-sea/software-and-configuration ()

这里我们直接使用编写配置文件,然后读取配置文件的方式 创建 Druid 数据库连接池的方式

注意编写配置文件是以.properties后缀的,而且是创建在 src 目录下的配置文件的信息。

这里我们创建的 Druid 配置文件的名为druid.properties

如下使用 IDEA 创建.properties的文件

下面是druid.properties配置文件的编写:

driverClassName=com.mysql.cj.jdbc.Driver#?rewriteBatchedStatements=true 批量处理打开url=jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=trueusername=rootpassword=MySQL123#初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时initialSize=10#最小连接池数量minIdle=5#最大连接池数量maxActive=20#获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。maxWait=5000#属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 监控统计用的filter:stat日志用的filter:log4j防御sql注入的filter:wallfilters=wall#不要加空格以及;分号,因为无论是空格还是分号都会被识别成对象匹配。防止匹配失败

下面是其他的有关 Druid 配置参数信息,大家可以自行参考,斟酌添加上

通过读取配置文件信息,创建 Druid 数据库连接池,再获取其中的连接

package Blogs.blogs04;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.sql.Connection;import java.util.Properties;public class DruidTest {public static void main(String[] args) {// 读取配置文件的方式一:InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");try {// 读取配置文件的方式二:FileInputStream io = new FileInputStream(new File("src/druid.properties"));// 创建对象获取到读取的配置文件中的关键字/属性值Properties properties = new Properties();properties.load(io);// 通过传入读取配置文件信息对象,创建 druid数据库连接池DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);// 从创建的 druid数据库连接池中获取到连接Connection connection = dataSource.getConnection();System.out.println(connection); // 连接的地址System.out.println(connection.getClass()); // 类所在的包路径位置} catch (Exception e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出。}}}

同理将 创建 Druid 数据库连接池封装起来。注意:一个应用一个数据库连接池就足够了,方法的调用,写在static静态代码块中(和类一起加载到内存当中,仅仅执行一次,所有对象共用)。

具体实现如下:

public class JDBCUtils {private static DataSource dataSource = null;static {try {// 读取配置文件的方式二:FileInputStream io = new FileInputStream(new File("src/druid.properties"));// 创建对象获取到读取的配置文件中的关键字/属性值Properties properties = new Properties();properties.load(io);// 通过传入读取配置文件信息对象,创建 druid数据库连接池dataSource = DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出}}public static Connection getDruidConnection() {try {Connection connection = dataSource.getConnection();return connection;} catch (SQLException e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出}}}

测试 Druid 数据库连接池处理 5000次/5w次50w次 连接所消耗的时间:

具体代码如下:

package Blogs.blogs04;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;public class DruidTest {public static void main(String[] args) {// 读取配置文件的方式一:InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");try {// 读取配置文件的方式二:FileInputStream io = new FileInputStream(new File("src/druid.properties"));// 创建对象获取到读取的配置文件中的关键字/属性值Properties properties = new Properties();properties.load(io);// 通过传入读取配置文件信息对象,创建 druid数据库连接池DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);long start = System.currentTimeMillis(); // 获取到连接前的时间点:单位毫秒for(int i = 0; i < 5000; i++) {// 从创建的 druid数据库连接池中获取到连接Connection connection = dataSource.getConnection();if(connection != null) {try {connection.close(); // “归还连接”,不是关闭连接} catch (SQLException e) {throw new RuntimeException(e);}}}long end = System.currentTimeMillis(); // 获取到连接完毕后的时间点:单位毫秒System.out.println("5000次连接所消耗的时间:" +(end - start));} catch (Exception e) {throw new RuntimeException(e); // 将编译异常转换为运行异常抛出。}}}

7. 总结:

我们上述的这三种 C3P0,DBCP,Druid 数据库连接池(数据源) 都是第三方基于DataSource接口编写封装的,同时注意使用这三种数据库连接池,需要导入相关的jar包: C3P0:c3p0-0.9.1.2-jdk1.3.jarDBCP:Commons-dbcp.jar ( 连接池的实现架包 ),Commons-pool.jar( 连接池实现的依赖库 )Druid(德鲁伊)commons-dbutils-1.3.jarMysql数据库驱动/数据库连接池驱动 · 彩虹海/软件和配置 - 码云 - 开源中国 ()software-and-configuration/Mysql数据库驱动/数据库连接池驱动 at master · China-Rainbow-sea/software-and-configuration () 这三种 C3P0,DBCP,Druid 都有帮助文档,index.html大家不要忘记了它的存在。static 静态的是和类一起同时加载到内存到中的,就不要使用 “this.” 的引用了需要注意这三种数据库连接池的配置文件的编写,其中C3p0 默认配置文件名是 :c3p0-config.xml,而 DBCP以及 Druid(德鲁伊) 它们俩的配置文件是以.properties后缀的,都将它们三者的配置文件信息都存放在项目src目录下。读取配置文件的两种方式:

// 读取配置文件的方式一:InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");// 读取配置文件的方式二:FileInputStream io = new FileInputStream(new File("src/druid.properties"));// 创建对象获取到读取的配置文件中的关键字/属性值Properties properties = new Properties();properties.load(io);

一个应用一个数据库连接池,而不是创建一个连接,就创建一个数据库连接池,这样还不如不使用数据库连接池技术。当连接不够了,可以通过增加数据库连接池中的连接数量,我们可以把数据库连接池(数据源)比作是一个生产连接的工厂,工厂只需要一个,所以一个应用只需要一个数据库连接池就足够了。注意:方法的调用是不能在类当中的,需要在代码块当中,方法代码块,static静态代码块(和类一起加载到内存当中,仅仅只执行一次,所有对象共用),该特点十分符合一个应用一个数据库连接池的特征,所有我们将创建数据库连接池放在类的 static 静态/静态代码块中执行。 数据库连接池技术的优点:资源重用更快的系统反应速度更快的系统反应速度统一的连接管理,避免数据库连接泄漏

8. 最后:

限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵——多多益善,谢谢大家,后会有期,江湖再见 !!!。最后,朋友,请留下你来过的证明 。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。