数据库连接池:什么是数据库连接池了?

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。

在Java中开源的数据库连接池有以下几种 :

  • 1、C3P0:是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate [2]  一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。
  • 2、Proxool:是一个Java SQL Driver驱动程序,提供了对选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中,完全可配置,快速、成熟、健壮。可以透明地为现存的JDBC驱动程序增加连接池功能。
  • 3、Jakarta DBCP:DBCP是一个依赖Jakartacommons-pool对象池机制的数据库连接池。DBCP可以直接的在应用程序中使用。
  • 4、DDConnectionBroker:是一个简单、轻量级的数据库连接池。
  • 5、DBPool:是一个高效、易配置的数据库连接池。它除了支持连接池应有的功能之外,还包括了一个对象池,使用户能够开发一个满足自己需求的数据库连接池。
  • 6、XAPool:是一个XA数据库连接池。它实现了javax.sql.XADataSource并提供了连接池工具。
  • 7、Primrose:是一个Java开发的数据库连接池。当前支持的容器包括Tomcat4&5、Resin3与JBoss3。它同样也有一个独立的版本,可以在应用程序中使用而不必运行在容器中。Primrose通过一个WEB接口来控制SQL处理的追踪、配置,以及动态池管理。在重负荷的情况下可进行连接请求队列处理。
  • 8、SmartPool:是一个连接池组件,它模仿应用服务器对象池的特性。SmartPool能够解决一些临界问题如连接泄漏(connection leaks)、连接阻塞、打开的JDBC对象(如Statements、PreparedStatements)等。SmartPool的特性包括: 支持多个pool,自动关闭相关联的JDBC对象,在所设定time-outs之后察觉连接泄漏,追踪连接使用情况,强制启用最近最少用到的连接,把SmartPool“包装”成现存的一个pool
  • 9、MiniConnectionPoolManager:是一个轻量级JDBC数据库连接池。它只需要Java1.5(或更高)并且没有依赖第三方包。
  • 10、BoneCP:是一个快速、开源的数据库连接池。帮用户管理数据连接,让应用程序能更快速地访问数据库。比C3P0/DBCP连接池速度快25倍。
  • 11、Druid:Druid不仅是一个数据库连接池,还包含一个ProxyDriver、一系列内置的JDBC组件库、一个SQL Parser。
  • 支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等。
  • Druid针对Oracle和MySql做了特别优化,比如:
  1. Oracle的PS Cache内存占用优化

  2. MySql的ping检测优化

  3. Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,这是一个手写的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便。
  4. 简单SQL语句用时10微秒以内,复杂SQL用时30微秒。
  5. 通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。Druid防御SQL注入攻击的WallFilter,就是通过Druid的SQL Parser分析语义实现的

本篇文章主要来看下C3p0和DBCP:

  1. DBCP:
方式1:
BasicDataSource source = new BasicDataSource();
source.setDriverClassName("com.mysql.jdbc.Driver");
source.setUrl("jdbc:mysql:///day11");
source.setUsername("root");
source.setPassword("root");方式2:
Properties prop = new Properties();
prop.load(new FileReader("dbcp.properties"));
BasicDataSourceFactory factory = new BasicDataSourceFactory();
DataSource source = factory.createDataSource(prop);

配置文件中配置,JDBC.properties:

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///
username=root
password=root
#<!-- 初始化连接 -->
initialSize=10
#最大连接数量
maxActive=50
#<!-- 最大空闲连接 -->
maxIdle=20
#<!-- 最小空闲连接 -->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000
  • C3P0数据源:
方式1:
ComboPooledDataSource source = new ComboPooledDataSource();
source.setDriverClass("com.mysql.jdbc.Driver");
source.setJdbcUrl("jdbc:mysql:///day11");
source.setUser("root");
source.setPassword("root");方式2:
ComboPooledDataSource source = new ComboPooledDataSource();

在类加载目录下名称为c3p0-config.xml的配置文件中配置:

<c3p0-config><default-config><property name="driverClass">com.mysql.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql:///day11</property><property name="user">root</property><property name="password">root</property></default-config>
</c3p0-config>

tomcat内置的数据源(DBCP):
1.如何为tomcat配置数据源

  • tomcat/conf/context.xml文件中配置<Context>配置在这个位置的信息将会被所有的web应用所共享
  • tomcat/conf/[engin]/[Host]/context.xml文件中可以配置<Context>标-签,这里配置的信息将会被这台虚拟主机中的所有web应用所共享
  • ~tomcat/conf/server.xml文件中的<Host>标签中配置<Context>标签,这是web应用的第一种配置方式,在这个标签中配置的信息将只对当前web应用起作用
  • ~tomcat/conf/[engin]/[Host]/自己创建一个.xml文件,在这个文件中使用<Context>标签配置一个web应用,这是web应用第二种配置方式,在这个<Context>标签中配置的信息将只会对当前web应用起作用
  • ~web应用还有第三种配置方式:将web应用直接放置到虚拟主机管理的目录.此时可以在web应用的META-INF文件夹下创建一个context.xml文件,在其中可以写<Context>标签进行配置,这种配置信息将只会对当前web应用起作用

配置的方式:在META-INF下创建一个context.xml

<Resource name="mySource"auth="Container"type="javax.sql.DataSource"username="root"password="root"driverClassName="com.mysql.jdbc.Driver"url="jdbc:mysql:///day11"maxActive="8"maxIdle="4"/>

2.数据源是配置好了,那么如何在程序中获取这个数据源
想要访问jndi就必须在Servlet中才能执行下列代码:在init的方法中执行以下操作:

Context initCtx = new InitialContext();
Context jndi = (Context) initCtx.lookup("java:comp/env");
DataSource source = jndi.lookUp("mySource");
//代码如下:
@Override
public void init() throws ServletException {
try{
//通过穿件这个容器
Context initCtx = new InitialContext();
//通过容器中的java:comp/env去找jndi
Context jndi = (Context) initCtx.lookup("java:comp/env");
//jndi去找配置的数据源;
DataSource source = (DataSource) jndi.lookup("mySource");
//通过找到的数据源获取连接
Connection conn = source.getConnection();
//获取连接后开是执行sql语句;
PreparedStatement ps = conn.prepareStatement("select * from account");
ResultSet rs = ps.executeQuery();
while(rs.next()){
String name = rs.getString("name");
System.out.println(name);
}
rs.close();
ps.close();
conn.close();}catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}

元数据的操作:
c3p0的基础来操作:
1.先配置c3p0的数据文件

<?xml version="1.0" encoding="utf-8"?>
<c3p0-config><default-config><property name="driverClass">com.mysql.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql:///blob?generateSimpleParameterMetadata=true</property><property name="user">root</property><property name="password">123</property></default-config>
</c3p0-config>

2.通过Databasematadata获取

public class DataBaseMeataDataDemo {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
//存储数据源接口池。
ComboPooledDataSource source = new ComboPooledDataSource();
try{
conn = source.getConnection();
//--获取当前数据库的元数据
DatabaseMetaData metaData = conn.getMetaData();
//----获取数据库连接时使用的URL
String url = metaData.getURL();
System.out.println(url);
//----获取数据库的用户名
String username = metaData.getUserName();
System.out.println(username);
//----获取驱动的名称
String driverName = metaData.getDriverName();
System.out.println(driverName);
//----获取数据库中指定表的主键信息
rs = metaData.getPrimaryKeys(null, null, "account");
while(rs.next()){
short cseq = rs.getShort("KEY_SEQ");
String cname = rs.getString("COLUMN_NAME");
System.out.println(cseq+":"+cname);
}
//----获取表
rs = metaData.getTables(null, null, "%", new String[]{"TABLE"});
while(rs.next()){
String tabName = rs.getString("TABLE_NAME");
System.out.println(tabName);
}}catch (Exception e) {
e.printStackTrace();
}finally{
DbUtils.closeQuietly(conn, ps, rs);
}
}
}

3.//获取参数源数据;
//通过c3p0的配置config信息,然后用ComboPooledDataSource source = new ComboPooledDataSource();
//来获取连接
•获得代表PreparedStatement元数据的ParameterMetaData对象。

public class PMMetaDataDemo {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
ComboPooledDataSource source = new ComboPooledDataSource();
try{
conn = source.getConnection();
ps = conn.prepareStatement("select * from account where name=? and money=?");
//--获取参数元数据
ParameterMetaData metaData = ps.getParameterMetaData();
//----参数的个数
int count = metaData.getParameterCount();
System.out.println(count);
//----获取参数的类型
String type = metaData.getParameterTypeName(1);
System.out.println(type);
String type2 = metaData.getParameterTypeName(2);
System.out.println(type2);}catch (Exception e) {
e.printStackTrace();
}finally{
DbUtils.closeQuietly(conn, ps, rs);
}
}
}

4.结果集元数据

ResultSet. getMetaData()
获得代表ResultSet对象元数据的ResultSetMetaData对象
public class RSMetaDataDemo {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
ComboPooledDataSource source = new ComboPooledDataSource();
try{
conn = source.getConnection();
ps = conn.prepareStatement("select * from account");
rs = ps.executeQuery();
//--获取结果集元数据
ResultSetMetaData metaData = rs.getMetaData();
//----获取结果集中的列数
int cc = metaData.getColumnCount();
//System.out.println(cc);
//----获取结果集中指定列的名称
//String cn = metaData.getColumnName(2);
//System.out.println(cn);
//----获取结果集中指定列的类型的名称
//String ct = metaData.getColumnTypeName(3);
//System.out.println(ct);System.out.println("-------------------------------------------------------");
for(int i = 1;i<=cc;i++){
String cn = metaData.getColumnName(i);
String ct = metaData.getColumnTypeName(i);
System.out.print(cn+":"+ct+"\t\t");
}
System.out.println();
System.out.println("-------------------------------------------------------");
while(rs.next()){
for(int i =1 ;i<=cc;i++){
Object obj = rs.getObject(i);
System.out.print(obj+"\t\t\t");
}
System.out.println();
}System.out.println("-------------------------------------------------------");}catch (Exception e) {
e.printStackTrace();
}finally{
DbUtils.closeQuietly(conn, ps, rs);
}
}
}

apache-dbutils框架:
commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。因此dbutils成为很多不喜欢hibernate的公司的首选。
API介绍:

  • •org.apache.commons.dbutils.QueryRunner --- 核心
  • •org.apache.commons.dbutils.ResultSetHandler

•工具类DBUtils 

org.apache.commons.dbutils.DbUtils、
需要传递一个数据源然后获取连接;原理也是c3p0在实现的时候要配置c3p0文件:文件如下:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///blob
user=root
password=123
工具类
实现查询:

/**
* DbUtils方式实现查询
* @throws SQLException
*/
public void find2() throws SQLException{
//需要传一个数据元进去
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
List<Account>list = runner.query("select * from account where money>?"
, new ResultSetHandler<List<Account>>(){
public List<Account> handle(ResultSet rs) throws SQLException {
List<Account> list = new ArrayList<Account>();
while(rs.next()){
Account acc = new Account();
acc.setId(rs.getInt("id"));
acc.setName(rs.getString("name"));
acc.setMoney(rs.getDouble("money"));
list.add(acc);
}
return list;
}
}, 500);
System.out.println(list);
}
增删改
/**
* DBUtils方式实现增删改
* @throws SQLException
*/public void add2() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
runner.update("update account set money=? where name=?", 888,"a");
}

QueryRunner -- 两行代码搞定增删改查

(1)QueryRunner() --需要控制事务时,使用这组方法

  • int update(Connection conn, String sql) Execute an SQL INSERT, UPDATE, or DELETE query without replacement parameters.
  • int update(Connection conn, String sql, Object... params)  Execute an SQL INSERT, UPDATE, or DELETE query.
  • int update(Connection conn, String sql, Object param)  Execute an SQL INSERT, UPDATE, or DELETE query with a single replacement parameter.
  • <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh) Execute an SQL SELECT query without any replacement parameters.
  • <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)  Execute an SQL SELECT query with replacement parameters.

(2)QueryRunner(DataSource ds) --不需要控制事务用这组方法

  • int update(String sql) Executes the given INSERT, UPDATE, or DELETE SQL statement without any replacement parameters.
  • int update(String sql, Object... params)  Executes the given INSERT, UPDATE, or DELETE SQL statement.
  • int update(String sql, Object param)  Executes the given INSERT, UPDATE, or DELETE SQL statement with a single replacement parameter.
  • <T> T query(String sql, ResultSetHandler<T> rsh) Executes the given SELECT SQL without any replacement parameters.
  • <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)  Executes the given SELECT SQL query and returns a result object.

3.ResultSetHandler 实现类

  • ArrayHandler:把结果集中的第一行数据转成对象数组。
  • ArrayListHandler:把结果集中的每一行数据都转成一个对象数组,再存放到List中。
  • BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
  • BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
  • MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
  • MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
  • ColumnListHandler:将结果集中某一列的数据存放到List中。
  • KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里(List<Map>),再把这些map再存到一个map里,其key为指定的列。
  • ScalarHandler:获取结果集中第一行数据指定列的值,常用来进行单值查询

ResultSetHandler类的演示:

public class RSHanlderDemo {
//ScalarHandler:获取结果集中第一行数据指定列的值,常用来进行单值查询
//QueryRunner类使用可插入策略执行SQL查询以处理ResultSets。 这个类是线程安全的。
public void tes9() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
Long count = (Long)runner.query("select count(*) from account",new ScalarHandler());
System.out.println(count);
}
//KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里(List<Map>),再把这些map再存到一个map里,其key为指定的列。
public void tes8() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
Map<Object, Map<String, Object>> map = runner.query("select * from account where money>?", new KeyedHandler("id"),500);
System.out.println(map);
}
//ColumnListHandler:将结果集中某一列的数据存放到List中。
public void tes7() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
List<Object>list = runner.query("select * from account where money>?", new ColumnListHandler(3),500);
System.out.println(list);
}
//MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
public void tes6() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
List<Map<String, Object>> list = runner.query("select * from account where money>?", new MapListHandler(),500);
System.out.println(list);
}
//MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
public void tes5() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
Map<String, Object> map = runner.query("select * from account where money>?", new MapHandler(),500);
System.out.println(map);
}
//BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
public void tes4() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
List<Account>list = runner.query("select * from account where money>?", new BeanListHandler<Account>(Account.class),500);
System.out.println(list);
}
//BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
public void tes3() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
Account acc = runner.query("select * from account where money>?", new BeanHandler<Account>(Account.class),500);
System.out.println(acc);
}
//ArrayListHandler:把结果集中的每一行数据都转成一个对象数组,再存放到List中。
public void tes2() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
List<Object[]> list = runner.query("select * from account where money>?", new ArrayListHandler(),500);
System.out.println(list);
}
//ArrayHandler:把结果集中的第一行数据转成对象数组。然后进行返回
public void test1() throws SQLException{
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
Object[] objs = runner.query("select * from account where money>?", new ArrayHandler(),500);
System.out.println(objs);
}
}

数据库连接池,几种开源的数据库连接池相关推荐

  1. 建立数据库时连接出错_PHP的福音!支持多数据库连接,高性能的开源MySQL连接池...

    对于很多 PHP 开发者来说,连接数据库一直是个让人头疼的问题,那么今天 Gitee 为大家介绍的就是一款一个基于 MySQL 协议,Swoole 开发的MySQL数据库连接池. 项目名称:SMPro ...

  2. 数据库连接的五种方式讲解

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 JDBC:获取数据库连接的5种方式 获取数据库连接前,我们需要做一些前期准备: 在项目工程中导入数据库连接相关数据库驱动(也就是第三方 ...

  3. 开源数据库连接池之Tomcat内置连接池

    本篇介绍几种开源数据库连接池,同时重点讲述如何使用Tomcat服务器内置的数据库连接池. 之前的博客已经重点讲述了使用数据库连接池的好处,即是将多次创建连接转变为一次创建而使用长连接模式.这样能减少数 ...

  4. oracle mysql连接池配置文件_数据库连接池两种配置方式详解

    数据库连接池: 负责分配.管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而再不是重新建立一个:释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接 ...

  5. java 连接池 druid_从零开始学 Java - 数据库连接池的选择 Druid

    我先说说数据库连接 数据库大家都不陌生,从名字就能看出来它是「存放数据的仓库」,那我们怎么去「仓库」取东西呢?当然需要钥匙啦!这就是我们的数据库用户名.密码了,然后我们就可以打开门去任意的存取东西了. ...

  6. javaweb mysql 连接池 c3p0 配置_JavaWeb基础—数据库连接池DBCP、C3P0

    一.基本概念 数据库连接池负责分配.管理和释放数据库连接 数据库连接池:(池用map来实现居多) 用处:为了可重用(销毁创建麻烦,开销大)(招培训老师的例子) 二.编写实现数据库连接池 池参数: 初识 ...

  7. mysql连接池_数据库技术:数据库连接池,Commons DbUtils,批处理,元数据

    Database Connection Pool Introduction to Database Connection Pool 实际开发中"获得连接"或"释放资源&q ...

  8. java连接池 dbcp 样例_DBCP数据库连接池的简单使用

    0.DBCP简介 DBCP(DataBase connection pool)数据库连接池是 apache 上的一个Java连接池项目.DBCP通过连接池预先同数据库建立一些连接放在内存中(即连接池中 ...

  9. eclipse链接mysql数据池配置_Tomcat+mysql+eclipse数据库连接池配置

    一.开发工具 1.tomcat版本:tomcat5.5.27 2.mysql版本:mysql 5.1 3.数据库驱动程序:mysql-connector-java-5.1.9 4.eclipse版本: ...

最新文章

  1. 必读:ICLR 2020 的50篇推荐阅读论文
  2. 版本发布后软件测试人员要做的工作
  3. C语言 之建立静态链接库
  4. 新基建数据中心如何建?附建设导则
  5. C#-自动(也叫隐式)类型转换及规则 018
  6. if-else运用及技巧(C# 参考)
  7. Java+Windows+ffmpeg实现视频转换
  8. PKU 3013 Big Christmas Tree 最短路 spfa
  9. 深入理解ArrayList 和 LinkedList 区别
  10. 数组 -- removeElement -- 图解
  11. mysql登录密码enc_SpringBoot项目mysql配置文件密码加密(jasypt)
  12. 官方澄清丨Gartner并未组织评选OpenStack八大厂商
  13. 汇编语言 数据寄存器AX、BX、CX、DX
  14. java读写excel,解决poi包中没有org.apache.poi.ss.usermodel.CellType的问题
  15. 手持小电风扇原理图挂脖小风扇电路图
  16. 【题解】LuoGu1512:伊甸园日历游戏
  17. 投简历的格式(第一分简历)
  18. jquery操作表格 合并单元格
  19. 虚拟机配置及系统加固
  20. 《那些年我们追过的Wrox精品红皮计算机图书》有奖活动

热门文章

  1. 用AI语音机器人有哪些需要注意事项
  2. QString 16进制,arg补0,从0xFFFFFFFFFFFFFFFA到0xFA
  3. 思想改变命运,95后脑瘫小伙转型网络工程师,你为什么不可以?
  4. MAML中few-shot (小样本)learning中数据集的处理
  5. 计算机策略组 网络,组策略怎么用 玩转电脑组策略技巧 (全文)
  6. CFileDialog 参数及返回值
  7. java指定图片的dpi和存储大小kb
  8. Manjaro Linux使用必应图片桌面/锁屏壁纸,每天自动更换
  9. 苹果微信分身版ios_苹果手机ios14系统微信分身地址安装教程
  10. C语言:求高次方数的尾数