数据库连接池

传统模式

使用数据库的传统模式:

  • 在主程序(servlet、beans等)中建立数据库连接;
  • 进行 SQL 操作;
  • 断开数据库连接。

这种模式存在的问题:

  • JDBC 连接数据库的方式(四个步骤:加载配置、读取配置、加载驱动、获取连接),会消耗大量的资源和时间,且连接资源没有得到很好的重复利用;
  • 获取一次数据库连接,使用完成后都得关闭连接;
  • 不能控制被创建的连接对象数。

数据库连接池技术

基本思想:为数据库连接建立一个“缓冲池”,预先在缓冲池中放入一定数量的连接,当需要建立数据库连接是,只需要从“缓冲池”中取出一个,使用完毕之后再放回去。

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复利用一个现有的数据库连接,而不是重新建立一个。

数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。

数据库连接池的优点:

  • 资源重用;
  • 更快的响应速度和更少的资源消耗;
  • 统一的连接管理,避免数据库连接泄露。

开源的数据库连接池

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

DataSource 通常被称为数据源,它包含连接池和连接池管理两个部分。

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

注意

  • 数据源和数据库连接不同,数据源无需创建多个,它是产生数据库连接的工厂,因此整个应用只需要一个数据源即可
  • 当数据库访问结束后,程序还是像以前一样关闭数据库连接:connnection.close(),但它并没有关闭数据库的物理连接,它仅仅把数据库连接释放,归还给了数据库连接池。

开源的数据库连接池:

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

  1. package cn.parzulpan.jdbc.ch08;
  2. import com.mchange.v2.c3p0.ComboPooledDataSource;
  3. import com.mchange.v2.c3p0.DataSources;
  4. import org.junit.Test;
  5. import java.sql.Connection;
  6. /**
  7. * @Author : parzulpan
  8. * @Time : 2020-12-01
  9. * @Desc : c3p0 数据库连接池
  10. */
  11. public class C3P0Test {
  12. // 连接方式一:不推荐
  13. @Test
  14. public void testGetConnection1() throws Exception{
  15. // 获取 c3p0 数据库连接池
  16. ComboPooledDataSource cpds = new ComboPooledDataSource();
  17. cpds.setDriverClass("com.mysql.jdbc.Driver");
  18. cpds.setJdbcUrl("jdbc:mysql://localhost:3306/test?useSSL=false");
  19. cpds.setUser("parzulpan");
  20. cpds.setPassword("parzulpan");
  21. //
  22. cpds.setInitialPoolSize(10);
  23. Connection connection = cpds.getConnection();
  24. System.out.println(connection);
  25. }
  26. // 连接方式二:使用配置文件,推荐
  27. // 使用时,需要将 cpds 声明为 static,然后用 static 代码块为 cpds 赋值
  28. @Test
  29. public void testGetConnection2() throws Exception{
  30. ComboPooledDataSource cpds = new ComboPooledDataSource("helloc3p0");
  31. Connection connection = cpds.getConnection();
  32. System.out.println(connection);
  33. // 销毁 c3p0 数据库连接池,慎用
  34. // DataSources.destroy(cpds);
  35. }
  36. }
  1. <!-- c3p0配置文件-->
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <c3p0-config>
  4. <named-config name="helloc3p0">
  5. <!-- 获取连接的基本信息-->
  6. <property name="driverClass">com.mysql.jdbc.Driver</property>
  7. <property name="jdbcUrl">jdbc:mysql://localhost:3306/test?useSSL=false</property>
  8. <property name="user">parzulpan</property>
  9. <property name="password">parzulpan</property>
  10. <!-- 数据库连接池的管理的相关属性的设置-->
  11. <!-- 若数据库连接池中连接数不足时,一次向数据库服务器申请的连接数-->
  12. <property name="acquireIncrement">5</property>
  13. <!-- 初始化数据库连接池时连接的数量-->
  14. <property name="initialPoolSize">5</property>
  15. <!-- 数据库连接池中的最小的数据库连接数-->
  16. <property name="minPoolSize">5</property>
  17. <!-- 数据库连接池中的最大的数据库连接数-->
  18. <property name="maxPoolSize">10</property>
  19. <!-- 数据库连接池可以维护的 Statement 的个数 -->
  20. <property name="maxStatements">20</property>
  21. <!-- 每个连接同时可以使用的 Statement 对象的个数 -->
  22. <property name="maxStatementsPerConnection">5</property>
  23. </named-config>
  24. </c3p0-config>

  1. package cn.parzulpan.jdbc.ch08;
  2. import org.apache.commons.dbcp.BasicDataSource;
  3. import org.apache.commons.dbcp.BasicDataSourceFactory;
  4. import org.junit.Test;
  5. import javax.sql.DataSource;
  6. import java.io.InputStream;
  7. import java.sql.Connection;
  8. import java.util.Properties;
  9. /**
  10. * @Author : parzulpan
  11. * @Time : 2020-12-01
  12. * @Desc : dbcp 数据库连接池
  13. */
  14. public class DBCPTest {
  15. // 连接方式一:不推荐
  16. @Test
  17. public void testGetConnection1() throws Exception{
  18. BasicDataSource bds = new BasicDataSource();
  19. bds.setDriverClassName("com.mysql.jdbc.Driver");
  20. bds.setUrl("jdbc:mysql://localhost:3306/test?useSSL=false");
  21. bds.setUsername("parzulpan");
  22. bds.setPassword("parzulpan");
  23. bds.setInitialSize(10);
  24. Connection connection = bds.getConnection();
  25. System.out.println(connection);
  26. }
  27. // 连接方式二:使用配置文件,推荐
  28. // 使用时,需要将 dataSource 声明为 static,然后用 static 代码块为 dataSource 赋值
  29. @Test
  30. public void testGetConnection2() throws Exception{
  31. Properties properties = new Properties();
  32. InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties");
  33. properties.load(is);
  34. DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);
  35. Connection connection = dataSource.getConnection();
  36. System.out.println(connection);
  37. }
  38. }
  1. # dbcp 配置文件
  2. driverClassName=com.mysql.jdbc.Driver
  3. url=jdbc:mysql://localhost:3306/test?useSSL=false
  4. username=parzulpan
  5. password=parzulpan
  6. initialSize=10

  1. package cn.parzulpan.jdbc.ch08;
  2. import com.alibaba.druid.pool.DruidDataSourceFactory;
  3. import org.junit.Test;
  4. import javax.sql.DataSource;
  5. import java.io.InputStream;
  6. import java.sql.Connection;
  7. import java.util.Properties;
  8. /**
  9. * @Author : parzulpan
  10. * @Time : 2020-12-01
  11. * @Desc : Druid 数据库连接池
  12. */
  13. public class DruidTest {
  14. // 连接方式一:使用配置文件,推荐
  15. // 使用时,需要将 dataSource 声明为 static,然后用 static 代码块为 dataSource 赋值
  16. @Test
  17. public void testGetConnection1() throws Exception{
  18. Properties properties = new Properties();
  19. InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
  20. properties.load(is);
  21. DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
  22. Connection connection = dataSource.getConnection();
  23. System.out.println(connection);
  24. }
  25. }
  1. # Druid 配置文件
  2. driverClassName=com.mysql.jdbc.Driver
  3. url=jdbc:mysql://localhost:3306/test?useSSL=false
  4. username=parzulpan
  5. password=parzulpan
  6. initialSize=10
  7. maxActive=20
  8. maxWait=1000
  9. filters=wall

练习和总结

【JDBC核心】数据库连接池的更多相关文章

  1. 数据库连接JDBC和数据库连接池C3P0自定义的java封装类

    数据库连接JDBC和数据库连接池C3P0自定义的java封装类 使用以下的包装类都需要自己有JDBC的驱动jar包: 如 mysql-connector-java-5.1.26-bin.jar(5.1 ...

  2. Java -- JDBC 学习--数据库连接池

    JDBC数据库连接池的必要性 在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤: 在主程序(如servlet.beans)中建立数据库连接. 进行sql操作 断开数据库连接. 这种模式开 ...

  3. JDBC【数据库连接池、DbUtils框架、分页】

    1.数据库连接池 什么是数据库连接池 简单来说:数据库连接池就是提供连接的... 为什么我们要使用数据库连接池 数据库的连接的建立和关闭是非常消耗资源的 频繁地打开.关闭连接造成系统性能低下 编写连接 ...

  4. Java Web(九) JDBC及数据库连接池及DBCP,c3p0,dbutils的使用

    DBCP.C3P0.DBUtils的jar包和配置文件(百度云盘):点我下载 JDBC JDBC(Java 数据库连接,Java Database Connectify)是标准的Java访问数据库的A ...

  5. 基于JDBC的数据库连接池技术研究与应用

    引言 近年来,随着Internet/Intranet建网技术的飞速发展和在世界范围内的迅速普及,计算机 应用程序已从传统的桌面应用转到Web应用.基于B/S(Browser/Server)架构的3层开 ...

  6. spring配置tomcat jdbc pool数据库连接池

    <bean id="sqliteDataSource" class="org.apache.tomcat.jdbc.pool.DataSource" de ...

  7. JavaEE JDBC 了解数据库连接池

    了解数据库连接池 @author ixenos 数据库连接是有限的资源,如果用户需要离开应用一段时间,那么他占用的连接就不应该保持开放状态: 另一方面,每次查询都获取连接并在随后关闭它的代价也很高. ...

  8. JDBC和数据库连接池

    JDBC是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成. ​ ● JDBC ​ ● C3P0 ​ ● DRUID 一.JDBC ...

  9. 关于jdbc和数据库连接池的关系(不是封装的关系)

    你都说是数据库连接池了.那就是连接数据库用的.JDBC是java封装的对数据库的操作.当然你可以自己进一步封装.数据库连接池是JDBC使用的前提,如果连数据库连接池都没连上,JDBC的操作就谈不上了. ...

  10. Jdbc druid数据库连接池

    //测试类package druid; import util.JdbcUtilsDruid; import java.sql.Connection; import java.sql.Date; im ...

随机推荐

  1. 图论-zkw费用流

    图论-zkw费用流 模板 这是一个求最小费用最大流的算法,因为发明者是神仙zkw,所以叫zkw费用流(就是zkw线段树那个zkw).有些时候比EK快,有些时候慢一些,没有比普通费用流算法更难,所以学z ...

  2. 关于微信NFC功能开发的链接总结

    特此申明:若有侵权,请联系我,我会第一时间删除 一. 小程序开发一般流程: 首先调用 wx.getHCEState(OBJECT), 判断设备是否支持NFC,(ios,android兼容性处理) 调用 ...

  3. git 远端版本回退

    情景:本地更改推送远端后,想要回退到自己推送之前的某个版本. 比如想回退的分支为 test 分支. 风险:远端回退到某一版本后,之后的所有推送都没了(对应的日志记录也没了).如果是团队开发,不仅自己推 ...

  4. (byte & 0xff)操作

    先看一段代码: @Test public void test(){ byte a = -5; byte b = 12; System.out.println(a); System.out.printl ...

  5. js下 Day12、案例

    一.垃圾分类 效果图: 功能思路分析: 1. 鼠标按下 (1) 获取鼠标到元素的距离(e.offsetX) (2) 开启开关变量 (3) 获取事件源 (4) 记录垃圾初始位置 ​  2. 鼠标移动 ( ...

  6. dropload.min.js 下拉刷新后,无法上拉加载更多

    使用方法 1.引入文件 <script src="/app/media/js/dropload.min.js"></script> 111111111111 ...

  7. 同学你会hello world吗? 给我讲清楚点

    少点代码,多点头发 本文已经收录至我的GitHub,欢迎大家踊跃star 和 issues. https://github.com/midou-tech/articles 面试官超级喜欢问hello ...

  8. MySQL 存储函数的创建、调用、查找

    MySQL存储函数(自定义函数),函数一般用于计算和返回一个值,可以将经常需要使用的计算或功能写成一个函数 1.创建存储函数:使用 create function关键字 2.调用存储函数: 3.示例: ...

  9. os模块和os.path模块常用方法

    今天和大家分享python内置模块中的os模块和os.path模块. 1.什么是模块呢? 在计算机开发过程中,代码越写越多,也就越来越难以维护,所以为了可维护的代码,我们会把函数进行分组,放在不同的文 ...

  10. setTimeout 是到了xx ms 就执行吗,了解浏览器的 Event-Loop 机制

    要想 JavaScript 玩得溜,还得了解波 JavaScript 执行机制/(ㄒoㄒ)/~~. 个人博客:https://shansan.top 前言 最近看了波 JavaScript 相关的文章 ...