当前位置: 代码迷 >> 综合 >> 数据库连接池+jdbc框架commons-dbutils 学习笔记
  详细解决方案

数据库连接池+jdbc框架commons-dbutils 学习笔记

热度:36   发布时间:2023-12-20 21:14:36.0

嗯,看到一个java web项目用到这些知识,就准备整理,嗯,我并没有敲代码。加油生活。愿我自己。

                                                                                                                                                                                                                                                                     木开子   2019.1.20  

数据库连接池作用:

      数据库连接的建立和关闭是耗费系统资源的操作,在多层结构环境中,对系统的性能影响尤为明显。数据库连接池解决该问题,当应用程序启动时,系统主动建立足够的数据库连接,并将这些连接作为对象存储在内存中,组成一个连接池,当用户需要访问数据时,无需建立一个新的数据库连接,而是从连接池中读取一个已有的连接直接使用,使用完毕,无需关闭,将该连接放回连接池,以供下次请求访问。数据库连接的建立断开都是由数据库连接池自身进行管理的。

    在java 中,开源的数据库连接池有DBCP,C3P0,Proxool,DBpool和XAPool等。

DBCP数据源:

DBCP(DataBase Connection Pool,数据库连接池):是Apache软件基金组织下的开源连接池,该连接池依赖于该组织下的common-pool项目,也是tomcat使用的连接池。

单独使用DBCP需要在系统中增加两个jar包:Commons-dbcp.jar(连接池的实现),Commons-pool.jar(连接池实现的依赖库)

C3P0数据源:

C3P0实现了数据源和JNDI的绑定,支持jdbc3和jdbc2的标准扩展,目前使用C3P0的开源项目有Hibernate和Spring等框架。c3p0不仅可以自动清理不在使用的Connection,还可以自动清理Statement和ResultSet.

使用c3p0需要在系统中增加:c3p0.jar和mchange-Commons.jar连接池的实现。

public class C3P0Utils {private static C3P0Utils dbPool;private ComboPooledDataSource dataSource;static{dbPool  = new C3P0Utils();}public C3P0Utils(){try{dataSource = new ComboPooledDataSource();//使用C3P0的默认配置来创建数据源dataSource = new ComboPooledDataSource("javawebapp");//通过读取C3P0的xml配置文件创建数据源,C3P0的xml配置文件c3p0-config.xml必须放在src目录下//通过代码创建C3P0数据库连接池/* dataSource.setDriverClass("com.mysql.jdbc.Driver");dataSource.setJdbcUrl("jdbc:mysql://locathost:3306/bookstore");dataSource.setUser("root");dataSource.setPassword("mysql");dataSource.setInitialPoolSize(2);dataSource.setMinPoolSize(1);dataSource.setMaxPoolSize(10);dataSource.setMaxStatements(10);dataSource.setMaxIdleTime(60);*/}catch (PropertyVetoException e){throw new RuntimeException(e);}}public final static C3P0Utils getInstance(){return dbPool;}public final Connection getConnection(){try{return dataSource.getConnection();}catch (SQLException e){throw new RuntimeException("无法连接到数据源:",e);}}
}
<?xml version="1.0" encoding="UTF-8"?><c3p0-config><named-config name="javawebapp"> <property name="user">root</property><property name="password">mysql</property><property name="jdbcUrl">jdbc:mysql:///bookstore</property><property name="driverClass">com.mysql.jdbc.Driver</property><property name="acquireIncrement">2</property><property name="initialPoolSize">5</property><property name="minPoolSize">5</property><property name="maxPoolSize">10</property><property name="maxStatements">20</property> <property name="maxStatementsPerConnection">5</property></named-config>
</c3p0-config>

以c3p0-config.xml文件的形式。

DataSource(数据源):

该工厂用于提供到此 DataSource 对象所表示的物理数据源的连接。作为 DriverManager 工具的替代项,DataSource 对象是获取连接的首选方法。实现 DataSource 接口的对象通常在基于 JavaTM Naming and Directory Interface (JNDI) API 的命名服务中注册。

DataSource 接口由驱动程序供应商实现。共有三种类型的实现:

  1. 基本实现 - 生成标准的 Connection 对象
  2. 连接池实现 - 生成自动参与连接池的 Connection 对象。此实现与中间层连接池管理器一起使用。                                         
    private static ComboPooledDataSource ds = null; 
    // private static DataSource dataSource = null;  dataSource = new ComboPooledDataSource();
  3. 分布式事务实现 - 生成一个 Connection 对象,该对象可用于分布式事务,大多数情况下总是参与连接池。此实现与中间层事务管理器一起使用,大多数情况下总是与连接池管理器一起使用。

DataSource 对象的属性在必要时可以修改。例如,如果将数据源移动到另一个服务器,则可更改与服务器相关的属性。其优点在于,由于可以更改数据源的属性,所以任何访问该数据源的代码都无需更改。

通过 DataSource 对象访问的驱动程序本身不会向 DriverManager 注册。通过查找操作获取 DataSource 对象,然后使用该对象创建 Connection 对象。使用基本的实现,通过 DataSource 对象获取的连接与通过 DriverManager 设施获取的连接相同。

从以下版本开始:1.4

 

方法摘要
 Connection getConnection()
          尝试建立与此 DataSource 对象所表示的数据源的连接。
 Connection getConnection(String username, String password)
          尝试建立与此 DataSource 对象所表示的数据源的连接。

 

一、commons-dbutils简介 

  commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。因此dbutils成为很多不喜欢hibernate的公司的首选。一共有27个类,但真正常用的是三大组件十几个类:门面组件、结果处理组件和行处理组件,其中门面组件提供程序入口,并进行一些参数检验等,结果处理组件则是核心所在,因为返回的结果可以是map,可以是list可以是JavaBean,这一块的变化很大,所以抽象出一个组件出来应对这些变化,行处理组件是从结果处理组件中分离出来的,它是结果处理组件的基础,无论哪种处理器,最终都要与一行数据打交道,因此,单独抽象出这一组件。

  commons-dbutilsAPI介绍:

  • org.apache.commons.dbutils.QueryRunner
  • org.apache.commons.dbutils.ResultSetHandler

  工具类

  • org.apache.commons.dbutils.DbUtils

 

二、QueryRunner类使用讲解

  该类简单化了SQL查询,它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。无论是增删改查,都需要调用QueryRunner的方法,因此QueryRunner就是执行的入口。它的每个方法,都需要用户提供connection、handler、sql以及sql的参数,而返回的则是用户想要的结果,这可能是一个List,一个Javabean或者仅仅是一个Integer。
  QueryRunner类提供了两个构造方法:

  • 默认的构造方法
  • 需要一个 javax.sql.DataSource 来作参数的构造方法。
    QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());

2.1、QueryRunner类的主要方法

  public Object query(Connection conn, String sql, Object[] params, ResultSetHandler rsh) throws SQLException:

执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法会自行处理 PreparedStatement 和 ResultSet 的创建和关闭。
  public Object query(String sql, Object[] params, ResultSetHandler rsh) throws SQLException: 

几乎与第一种方法一样;唯一的不同在于它不将数据库连接提供给方法,并且它是从提供给构造方法的数据源(DataSource) 或使用的setDataSource 方法中重新获得 Connection。
  public Object query(Connection conn, String sql, ResultSetHandler rsh) throws SQLException :

执行一个不需要置换参数的查询操作。
  public int update(Connection conn, String sql, Object[] params) throws SQLException:

用来执行一个更新(插入、更新或删除)操作。
  public int update(Connection conn, String sql) throws SQLException:

用来执行一个不需要置换参数的更新操作。

 

 

三、ResultSetHandler接口使用讲解

  该接口用于处理java.sql.ResultSet,将数据按要求转换为另一种形式。
  ResultSetHandler接口提供了一个单独的方法:Object handle (java.sql.ResultSet .rs)

3.1、ResultSetHandler接口的实现类

 

ResultSetHandler 用于处理ResultSet的接口
AbstractKeyedHandler 将返回结果处理成键值对的抽象类
KeyedHandler

处理数据库返回结果,封装成一个Map,数据库表的一个列名为key,通常可以用主键,数据库中的一行结果以Map的形式作为value

BeanMapHandler 处理数据库返回结果,封装成一个Map,和KeyedHandler的唯一的不同是,每一行结果以Javabean的形式作为value
AbstractListHandler 将返回结果处理成链表的抽象类
ArrayListHandler

将返回结果处理成链表,这个链表的每个

元素都是一个Object数组,保存了数据库中对应的一行数据

ColumnListHandler

如果要取单独一列数据,可以用这个handler,用户指定列名,它返回这个

列的一个list

MapListHandler

和ArrayListHandler不同的是,链表的每个元素是个Map,这个Map代表数据库里的一行数据

ArrayHandler

将一行数据处理成object数组

BeanHandler

将一行数据处理成一个Java bean

BeanListHandler

将所有数据处理成一个list,list的元素时Java bean

MapHandler

将一行结果处理成一个Map

MapListHandler

将所有结果处理成一个list,list的元素时Map

ScalarHandler

这个类常常用于取单个数据,比如某一数据集的总数等等

行处理组件

RowProcessor 用于处理数据库中一行数据的接口
BasicRowProcessor 基本的行处理器实现类
BeanProcessor 通过反射将数据库数据转换成Javabean
package me.gacl.test;import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import me.gacl.util.JdbcUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.KeyedHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.Test;/**
* @ClassName: ResultSetHandlerTest
* @Description:测试dbutils各种类型的处理器
* @author: 孤傲苍狼
* @date: 2014-10-6 上午8:39:14
*
*/ 
public class ResultSetHandlerTest {@Testpublic void testArrayHandler() throws SQLException{QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());String sql = "select * from users";Object result[] = (Object[]) qr.query(sql, new ArrayHandler());System.out.println(Arrays.asList(result));  //list  toString()}@Testpublic void testArrayListHandler() throws SQLException{QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());String sql = "select * from users";List<Object[]> list = (List) qr.query(sql, new ArrayListHandler());for(Object[] o : list){System.out.println(Arrays.asList(o));}}@Testpublic void testColumnListHandler() throws SQLException{QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());String sql = "select * from users";List list = (List) qr.query(sql, new ColumnListHandler("id"));System.out.println(list);}@Testpublic void testKeyedHandler() throws Exception{QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());String sql = "select * from users";Map<Integer,Map> map = (Map) qr.query(sql, new KeyedHandler("id"));for(Map.Entry<Integer, Map> me : map.entrySet()){int  id = me.getKey();Map<String,Object> innermap = me.getValue();for(Map.Entry<String, Object> innerme : innermap.entrySet()){String columnName = innerme.getKey();Object value = innerme.getValue();System.out.println(columnName + "=" + value);}System.out.println("----------------");}}@Testpublic void testMapHandler() throws SQLException{QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());String sql = "select * from users";Map<String,Object> map = (Map) qr.query(sql, new MapHandler());for(Map.Entry<String, Object> me : map.entrySet()){System.out.println(me.getKey() + "=" + me.getValue());}}@Testpublic void testMapListHandler() throws SQLException{QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());String sql = "select * from users";List<Map> list = (List) qr.query(sql, new MapListHandler());for(Map<String,Object> map :list){for(Map.Entry<String, Object> me : map.entrySet()){System.out.println(me.getKey() + "=" + me.getValue());}}}@Testpublic void testScalarHandler() throws SQLException{QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());String sql = "select count(*) from users";  //[13]  list[13]int count = ((Long)qr.query(sql, new ScalarHandler(1))).intValue();System.out.println(count);}
}

该代码复制:http://www.cnblogs.com/xdp-gacl/p/4007225.html

三、DbUtils类使用讲解

  DbUtils :提供如关闭连接、装载JDBC驱动程序等常规工作的工具类,里面的所有方法都是静态的。JDBC助手方法的集合。这个类是线程安全的。主要方法如下:
  public static void close(…) throws java.sql.SQLException: DbUtils类提供了三个重载的关闭方法。这些方法检查所提供的参数是不是NULL,如果不是的话,它们就关闭Connection、Statement和ResultSet。
  public static void closeQuietly(…): 这一类方法不仅能在Connection、Statement和ResultSet为NULL情况下避免关闭,还能隐藏一些在程序中抛出的SQLEeception。
  public static void commitAndCloseQuietly(Connection conn): 用来提交连接,然后关闭连接,并且在关闭连接时不抛出SQL异常。 
  public static boolean loadDriver(java.lang.String driverClassName):这一方装载并注册JDBC驱动程序,如果成功就返回true。使用该方法,你不需要捕捉这个异常ClassNotFoundException。

嗯,先就做这么多,以后在补充吧!2019.1.23

 

  相关解决方案