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 进阶——连接池
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容

  • 本文包括传统JDBC的缺点连接池原理自定义连接池开源数据库连接池DBCP连接池C3P0连接池Tomcat内置连接池...
    廖少少阅读 16,717评论 0 37
  • 前言 数据库连接池在Java数据库相关中间件产品群中,应该算是底层最基础的一类产品,作为企业应用开发必不可少的组件...
    许da广阅读 7,141评论 2 27
  • 最原始的数据库连接就是我们打开一个连接,使用过后再关闭该链接来释放资源。频繁的新建打开再关闭连接对jvm和数据库都...
    野柳阅读 6,320评论 1 11
  • 以一个xx.png图片来说内部的结构如下: 一开始是.png 后面紧跟 宽 高 然后是数据 最后是图片描述(拍摄时...
    刘书亚的天堂之路阅读 1,761评论 2 2
  • 又到一周做自然笔记啦!这周的主题是……昆虫! 恰巧就看到了小朋友养的蚕宝宝了,已处于“眠”时期的它们开始吐丝了哦⊙ ⊙
    db21dd77f543阅读 352评论 0 2