嗯,看到一个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
接口由驱动程序供应商实现。共有三种类型的实现:
- 基本实现 - 生成标准的
Connection
对象 - 连接池实现 - 生成自动参与连接池的
Connection
对象。此实现与中间层连接池管理器一起使用。
private static ComboPooledDataSource ds = null;
// private static DataSource dataSource = null;
dataSource = new ComboPooledDataSource();
- 分布式事务实现 - 生成一个
Connection
对象,该对象可用于分布式事务,大多数情况下总是参与连接池。此实现与中间层事务管理器一起使用,大多数情况下总是与连接池管理器一起使用。
DataSource
对象的属性在必要时可以修改。例如,如果将数据源移动到另一个服务器,则可更改与服务器相关的属性。其优点在于,由于可以更改数据源的属性,所以任何访问该数据源的代码都无需更改。
通过 DataSource
对象访问的驱动程序本身不会向 DriverManager
注册。通过查找操作获取 DataSource
对象,然后使用该对象创建 Connection
对象。使用基本的实现,通过 DataSource
对象获取的连接与通过 DriverManager
设施获取的连接相同。
从以下版本开始:1.4
方法摘要 | |
| |
| |
一、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