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

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

时间:2022-12-12 17:33:35浏览次数:56  
标签:jdbc commons QueryRunner sql new dbutils public 连接池


嗯,看到一个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();
  1. 分布式事务实现 - 生成一个 ​​Connection​​ 对象,该对象可用于分布式事务,大多数情况下总是参与连接池。此实现与中间层事务管理器一起使用,大多数情况下总是与连接池管理器一起使用。

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

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

从以下版本开始:1.4

 

方法摘要

​ Connection​

getConnection()​​           尝试建立与此 ​​DataSource​​ 对象所表示的数据源的连接。

​ Connection​

getConnection(String username, String​​           尝试建立与此 ​​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 {

@Test
public 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()
}

@Test
public 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));
}
}

@Test
public 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);
}

@Test
public 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("----------------");
}
}

@Test
public 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());
}
}


@Test
public 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());
}
}
}

@Test
public 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);
}
}

三、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

 

标签:jdbc,commons,QueryRunner,sql,new,dbutils,public,连接池
From: https://blog.51cto.com/u_13474506/5931216

相关文章

  • Sharding-JDBC 问题收集
    Sharding-JDBC问题收集简介Sharding-JDBC最早是当当网内部使用的一款分库分表框架,到2017年的时候才开始对外开源,这几年在大量社区贡献者的不断迭代下,功能也逐渐完善,现......
  • JDBC的快速入门
    JDBC的快速入门一、前置工作1.导入相关数据库的jar包2.右击jar包,点击AndasLibrary...二、代码实现1.注册驱动使用Class.forName();方法注册驱动,此时使用musql数据......
  • mysql/lightdb for pg/oracle jdbc大数据量插入优化
    10.10.6 大数据量插入优化在很多涉及支付和金融相关的系统中,夜间会进行批处理,在批处理的一开始或最后一般需要将数据回库,因为应用和数据库通常部署在不同的服务器,而且应用......
  • oracle/mysql/lightdb/postgresql java jdbc类型映射
    MySQL数据类型JAVA数据类型JDBCTYPE普通变量类型主键类型BIGINTLongBIGINT支持支持TINYINTByteTINYINT支持不支持SMALLINTShortSMALLINT支持不支持MEDIUMINTIntegerINTEGER......
  • Maven - oracle ojdbc jar包报错:Could not find artifact com.oracle:ojdbc8
    oracleojdbcjar包报错:Couldnotfindartifactcom.oracle:ojdbc8 在IDEA中引入一个新项目时,由于项目中引入了如下依赖:<dependency><groupId>c......
  • glibc-commons 依赖解析 版本错误,xxx is duplicate yyy
    glibc-commons安装了两个版本,导致依赖glibc-commons的很多软件包被安装了两个版本;解决办法就是先清除这些重复的已安装的软件,然后执行yumupdate将glibc-commons更......
  • JDBC编程
    1,一个入门查询postgresql数据库的例子,新建JDBCFirstDemo.java文件packagecom.jdbc.demo;importjava.sql.*;publicclassJDBCFirstDemo{publicstaticvoidma......
  • JDBC 数据库连接池
    jdbc的链接//1.导入数据库驱动Class.forName("com.mysql.jdbc.Driver");//2.获取连接对象try{Stringurl="jdbc:mysql://localhost:3306/student?useSSL=false";//......
  • 【开源项目】震惊JDBC查询比MyBatis查询慢
    震惊JDBC查询比MyBatis查询快?文章编写起始原因,在编写项目的时候碰到一个深坑,JDBC获取5000条数据,居然耗时261s,MyBatis同样的操作,耗时12s左右,震惊。看到这里下巴都快掉下来......
  • Apache Commons工具包系列不错的介绍文
    开源工具系列文章:ApacheCommonsLang(1):http://ray-yui.iteye.com/blog/1953020ApacheCommonsLang(2):http://ray-yui.iteye.com/blog/195......