Java 数据库连接池笔记

JDBC

Java 数据库连接(Java Database Connectivity,简称JDBC)是 Java 语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。

JDBC 的创建

使用 JDBC 访问数据库的流程:

  1. 加载 JDBC 驱动
  2. 连接数据库
  3. 执行 SQL 查询
  4. 从结果集中提取数据
  5. 处理结果集
  6. 清理环境,关闭所有的数据库资源,释放内存

关于 JDBC 更详细的介绍与使用:Java-MySQL连接

JDBC 的缺点

熟悉 JDBC 编程的,我们知道它存在很多缺点,如:

  1. 数据库连接,使用时创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响了数据库的性能。
  2. 将 sql 语句硬编码到java代码中,如果 sql 语句的修改,需要重新编译java代码,不利于系统的维护
  3. 向 preparedStatement 中设置参数,对占位符位置和参数值,硬编码在代码中,不利于系统的维护。
  4. 从 resultSet 中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,不利于系统的维护。

针对上述缺点,我们对应的解决方案:

  • 问题1:使用数据库的连接池管理数据库的连接。
  • 问题2:将 sql 语句配置到 xml 配置文件中,即使 sql 变化,不需要对 java 进行重新编译
  • 问题3:将 sql 语句和参数值配置到 xml 中
  • 问题4:将查询的结果自动的映射的 java 的对象

总的来说,我们主要会采用数据库连接池解决数据库频繁链接与释放问题,采用配置文件解决 sql 语句硬编码问题。

数据库连接池

连接池技术的核心思想是:连接复用,通过建立一个数据库连接池以及一套连接使用、分配、管理策略,使得该连接池中的连接可以得到高效、安全的复用,避免了数据库连接频繁建立、关闭的开销。另外,由于对 JDBC 中的原始连接进行了封装,从而方便了数据库应用对于连接的使用(特别是对于事务处理),提高了开发效率,也正是因为这个封装层的存在,隔离了应用的本身的处理逻辑和具体数据库访问逻辑,使应用本身的复用成为可能。

连接池的操作:

  1. 建立数据库连接池对象(服务器启动)。
  2. 按照事先指定的参数创建初始数量的数据库连接(即:空闲连接数)。
  3. 对于一个数据库访问请求,直接从连接池中得到一个连接。如果数据库连接池对象中没有空闲的连接,且连接数没有达到最大(即:最大活跃连接数),创建一个新的数据库连接。
  4. 存取数据库。
  5. 关闭数据库,释放所有数据库连接(此时的关闭数据库连接,并非真正关闭,而是将其放入空闲队列中。如实际空闲连接数大于初始空闲连接数则释放连接)。
  6. 释放数据库连接池对象(服务器停止、维护期间,释放数据库连接池对象,并释放所有连接)。

自定义数据库连接池

大致了解了数据库连接池的原理与创建方法,我们可以自己编写一个数据库连接池,而编写连接池需实现javax.sql.DataSource接口。DataSource接口中定义了两个重载的getConnection方法:

  Connection.getConnection() 

  Connection.getConnection(String username, String password) 

自定义一个类,实现DataSource接口,并实现连接池功能的步骤:

  1. 在自定义类的构造函数中批量创建Connection,并把创建的连接保存到一个集合对象中(LinkedList)。
  2. 在自定义类中实现Connection.getConnection方法,让getConnection方法每次调用时,从集合对象中取出一个Connection返回给用户。
  3. 当用户使用完Connection,不能调用Connection.close()方法,而要使用连接池提供关闭方法,即将Connection放回到连接池之中(把Connection存入集合对象中)。

注:Connection对象应保证将自己返回到连接池的集合对象中,而不要把Connection还给数据库。

实际编程时我们并不需要自己编写连接数据库代码,有一些开源组织提供了数据库连接池的实现,我们只要会使用即可。在我实习的公司,主要使用以下两种开源数据库连接池:

  • C3P0 数据库连接池
  • DBCP 数据库连接池

为此,就这两种数据库连接池,我做一简单的介绍。

C3P0 数据库连接池

C3P0 是一个开源的 JDBC 连接池,它实现了数据源和 JNDI 绑定,支持 JDBC3 规范和 JDBC2 的标准扩展。目前使用它的开源项目有Hibernate,Spring 等。

C3P0 所需 JAR 包: c3p0-0.9.2.1.jar 和 mchange-commons-java-0.2.3.4.jar

配置文件常用的属性:

####### c3p0 #######
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql://127.0.0.1:3306/test
c3p0.user=xxxx
c3p0.password=xxxxx

c3p0.initialPoolSize=10 //初始化连接数
c3p0.minPoolSize=10 //最大连接数
c3p0.maxPoolSize=30 //最小连接数
c3p0.maxIdleTime=30 //最大空闲时间 => 这就是为什么C3P0有自动回收的原因
c3p0.acquireIncrement=5 //新增连接数

当创建连接池时,一次性创建initialPoolSize 个连接,当连接使用完一次性创建 acquireIncrement 个连接,连接最大数量 maxPoolSize ,当连接池连接数量大于 minPoolSize ,经过 maxIdleTime 连接没有使用, 该连接将被释放。

C3P0 连接创建方式主要分为:配置文件形式和硬编码形式,这点和 DBCP 数据库连接池非常相似,唯一不同的就是配置文件命名规范不同,C3P0 配置文件必须命名为 c3p0-config.xml 或 c3p0-config.properties ,并且放在 src 目录下,而 DBCP 没有这样的要求。

DBCP 数据库连接池

DBCP(DataBase connection pool), 数据库连接池。是 apache 上的一个 java 连接池项目,也是 tomcat 默认使用的连接池组件。

DBCP 需要3个包:common-dbcp.jar,common-pool.jar,common-collections.jar

配置文件常用的属性:

####### dbcp #######
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test
username=xxxx
password=xxxxx

initialSize=10
# maxActive=10  // dbcp2中已将MaxActive设置为MaxTotal
maxTotal=30  // 可以在这个池中同时被分配的有效连接数的最大值,如设置为负数,则不限制
maxIdle=10  // 可以在池中保持空闲的最大连接数,超出设置值之外的空闲连接将被回收,如设置为负数,则不限制
minIdle=5   // 可以在池中保持空闲的最小连接数,超出设置值之外的空闲连接将被创建,如设置为0,则不创建

关于 C3P0 和 DBCP 配置文件更详细的说明,请自行了解。Demo 可参见我的GitHub仓库,后续会补充测试代码。

C3P0 与 DBCP 区别

  1. C3P0 自动回收空闲连接
  • 主要因为 maxIdleTime 属性,当连接池连接数量大于 minPoolSize ,经过 maxIdleTime 连接没有使用, 该连接将被释放
  1. C3P0 拥有 3 种配置方法,DBCP 拥有 2 种配置方法
  2. 对数据连接的处理方式,C3P0 提供最大空闲时间,DBCP 提供最大连接数
  • 前者当连接超过最大空闲连接时间时,当前连接就会被断掉。DBCP 当连接数超过最大连接数时,所有连接都会被断开。

参考链接

  1. 数据库连接池的工作原理
  2. JDBC 进阶——连接池

推荐阅读更多精彩内容

  • 本文包括传统JDBC的缺点连接池原理自定义连接池开源数据库连接池DBCP连接池C3P0连接池Tomcat内置连接池...
    廖少少阅读 15,143评论 0 37
  • 前言 数据库连接池在Java数据库相关中间件产品群中,应该算是底层最基础的一类产品,作为企业应用开发必不可少的组件...
    许da广阅读 6,370评论 1 26
  • 最原始的数据库连接就是我们打开一个连接,使用过后再关闭该链接来释放资源。频繁的新建打开再关闭连接对jvm和数据库都...
    野柳阅读 5,670评论 1 11
  • 以一个xx.png图片来说内部的结构如下: 一开始是.png 后面紧跟 宽 高 然后是数据 最后是图片描述(拍摄时...
    刘书亚的天堂之路阅读 1,276评论 2 2
  • 又到一周做自然笔记啦!这周的主题是……昆虫! 恰巧就看到了小朋友养的蚕宝宝了,已处于“眠”时期的它们开始吐丝了哦⊙ ⊙
    db21dd77f543阅读 205评论 0 2
  • 在空调的风声里 冷驱逐原本闷热的空气 楼板有些薄 楼上孩子的玩具掉落下来,咚的一声 夜色迷离 想着过去与未来 觉察...
    蒋菱阅读 62评论 0 1
  • 下午约起小伙伴去拍照,拍照地点为龙美术馆,之前一直想去,今天正好过去。 本来打算在外面取景的,但是很多不错的构图在...
    快乐平方LECEPIN阅读 118评论 0 0