第11章 数据库连接池与DBUtils工具
学习目标
- 了解什么是数据库连接池、了解DataSource接口的作用
- 掌握DBCP和C3P0数据库连接池的使用
- 了解DBUtils工具中常见的API
- 掌握使用DBUtils工具对数据库进行增删改查的操作
上一章讲解了JDBC的基本用法和操作,由于每操作一次数据库,都会执行一次创建和断开数据库Connection对象的操作,频繁的操作Connection对象十分影响数据库的访问效率,并且增加了代码量,所以在实际开发中,开发人员通常会使用数据库连接池来解决这些问题。
Apache组织提供了一个DBUtils工具类库,该类库实现了对JDBC的简单封装,能在不影响数据库访问性能的情况下,极大地简化JDBC的编码工作。
1 数据库连接池
1.1 什么是数据库连接池
(1) JDBC连接数据库的缺陷
在JDBC编程中,每次创建和断开Connection对象都会消耗一定的时间和IO资源。在Java程序与数据库之间建立连接时,数据库端要验证访问数据库用户名和密码,并且要为这个连接分配资源,Java程序则要把代表连接的java.sql.Connection对象等加载到内存中,所以建立数据库连接的开销很大,尤其是在大量的并发访问时。频繁地创建、断开数据库连接会影响数据库的访问效率,甚至导致数据库崩溃。
(2) 数据库连接池技术
为了避免频繁的创建数据库连接,工程师们提出了数据库连接池技术: 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用现有的数据库连接,而不是重新建立。
减少创建和断开数据库连接的次数,提高数据库的访问效率。 DBCP、C3P0、Druid--阿里
1.2 DataSource接口
为了获取数据库连接对象(Connection),JDBC提供了javax.sql.DataSource接口,它负责与数据库建立连接(数据源中存储了所有建立数据库连接的信息----数据库连接池),并定义了返回值为Connection对象的方法:
- 无参: Connection getConnection()
- 有参: Connection getConnection(String username,String password)
常用的开源组织提供数据源实现有:JNDI、DBCP、C3P0和阿里Druid
数据源用于管理数据库连接池。
1.3 DBCP数据源
DBCP是数据库连接池(DataBase Connection Pool)的简称,是Apache组织下的开源连接池实现,也是Tomcat服务器使用的连接池组件。单独使用DBCP数据源时,需要在应用程序中导入两个jar包:commons-dbcp2.jar、commons-poo2.jar(本例使用commons-dbcp2-2.9.0.jar、commons-pool2-2.11.1.jar。 )。
- commons-dbcp2.jar包是DBCP数据源的实现包,包含了所有数据库连接信息和数据库连接池初始化信息的方法,并实现了DataSource接口的getConnection()方法。commons-dbcp2.jar包中包含两个核心类,分别是BasicDataSourceFactory和BasicDataSource,它们都包含获取DBCP数据源对象的方法。
- commons-pool2.jar包是commons-dbcp2.jar包的依赖包,为commons-dbcp2.jar包中的方法提供了支持。
官网下载地址:
https://commons.apache.org/proper/commons-dbcp/download_dbcp.cgi
https://commons.apache.org/proper/commons-pool/download_pool.cgi
https://commons.apache.org/proper/commons-logging/download_logging.cgi
(1) DBCP常见配置项
分类 | 属性 | 描述 |
---|---|---|
必须项 | driverClassName | 数据库驱动名称 |
url | 数据库的地址 | |
username | 用户名 | |
password | 密码 | |
基本项(扩展) | maxActive | 最大连接数量 |
minIdle | 最小空闲连接数 | |
maxIdle | 最大空闲连接数 | |
initialSize | 初始化连接数 |
(2) BasicDataSource类的常用方法(7个set、1个getConnection())
方法名称 | 功能描述 |
---|---|
void setDriverClassName(String driverClassName) | 设置连接数据库的驱动名称 |
void setUrl(String url) | 设置连接数据库的路径 |
void setUsername(String username) | 设置数据库的登陆账号 |
void setPassword(String password) | 设置数据库的登录密码 |
void setInitialSize(int initialSize) | 设置数据库连接池初始化的连接数目 |
void setMaxActive (int maxIdle) | 设置数据库连接池最大活跃的连接数目 |
void setMinIdle(int minIdle) | 设置数据库连接池最小闲置的连接数目 |
Connection getConnection() | 从连接池中获取一个数据库连接 |
(3) 通过BasicDataSource类直接创建数据源对象
参照ch04创建ch11_ls项目(添加Web框架支持、设置模块的Tomcat库和Web\WEB-INF\lib目录库支持、设置工件、配置运行配置),
将Java 8:mysql-connector-java-8.0.30.jar、commons-dbcp2-2.9.0.jar、commons-pool2-2.11.1.jar、commons-logging-1.2.jar 粘贴到 Web\WEB-INF\lib。
cn.ls.Eg01_ls.java。
package cn.ls;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
public class Eg01_ls {
public static DataSource ds = null;
static {
// 获取DBCP数据库连接池实现类对象
BasicDataSource bds = new BasicDataSource();
// 设置连接数据库需要的配置信息
bds.setDriverClassName("com.mysql.cj.jdbc.Driver");
bds.setUrl("jdbc:mysql://公网ip:3306/jdbc_ls?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useSSL=false");
bds.setUsername("root");
bds.setPassword("******");
// 设置连接池的初始化连接参数
bds.setInitialSize(5);
bds.setMaxTotal(5);
//bds.setMaxActive(5);
ds = bds;
}
public static void main(String[] args) throws SQLException {
// 获取数据库连接对象
Connection conn = ds.getConnection();
//获取数据库连接信息
DatabaseMetaData metaData = conn.getMetaData();
//打印数据库连接信息
System.out.println("通过BasicDataSource类直接创建数据源对象【ls】\nURL="+metaData.getURL()
+",\nUserName="+metaData.getUserName()
+",\nDriverName="+metaData.getDriverName());
}
}
运行main方法截图如下:
(4) 通过BasicDataSourceFactory类读取配置文件创建数据源对象
src\dbcpconfig.properties。
#\u8FDE\u63A5\u8BBE\u7F6E
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://101.42.158.247:3306/jdbc_ls?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useSSL=false
username=root
password=****密码****.
#\u521D\u59CB\u5316\u8FDE\u63A5
initialSize=5
#\u6700\u5927\u8FDE\u63A5\u6570\u91CF
# maxActive=10
maxTotal=10
#\u6700\u5927\u7A7A\u95F2\u8FDE\u63A5
maxIdle=10
https://www.bejson.com/convert/unicode_chinese/ 请使用该网站转换上面的注释
cn.ls.Eg02_ls.java。
package cn.ls;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
public class Eg02_ls {
public static DataSource ds = null;
static {
// 新建一个配置文件对象
Properties prop = new Properties();
try {
// 通过类加载器找到文件路径,读配置文件
InputStream in = new Eg02_ls().getClass().getClassLoader().getResourceAsStream("dbcpconfig.properties");
// 把文件以输入流的形式加载到配置对象中
prop.load(in);
// 创建数据源对象
ds = BasicDataSourceFactory.createDataSource(prop);
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static void main(String[] args) throws SQLException {
// 获取数据库连接对象
Connection conn = ds.getConnection();
// 获取数据库连接信息
DatabaseMetaData metaData = conn.getMetaData();
// 打印数据库连接信息
System.out.println("通过BasicDataSourceFactory类读取配置文件创建数据源对象【ls】\nURL="+metaData.getURL()
+ "\nUserName=" + metaData.getUserName() + ",\nDriverName=" + metaData.getDriverName());
}
}
运行main方法截图如下:
1.4 C3P0数据源
C3P0是目前最流行的开源数据库连接池之一,它实现了DataSource数据源接口,支持JDBC2和JDBC3的标准规范,易于扩展并且性能优越,著名的开源框架Hibernate和 Spring使用的都是该数据源。(据可靠信息:C3P0连接池的作者其实是一个《星球大战》迷,C3P0就是其中的一个机器人名字,而且这个名称中包涵了Connection和Pool的单词字母。因此就叫了这个名字。)
官网下载地址:https://sourceforge.net/projects/c3p0/
c3p0-0.9.5.5.jar mchange-commons-java-0.2.19.jar
(1) C3P0类的常用方法(7个set、1个getConnection())
方法名称 | 功能描述 |
---|---|
void setDriverClass() | 设置连接数据库的驱动名称 |
void setJdbcUrl() | 设置连接数据库的路径 |
void setUser() | 设置数据库的登陆账号 |
void setPassword() | 设置数据库的登录密码 |
void setMaxPoolSize() | 设置数据库连接池最大的连接数目 |
void setMinPoolSize() | 设置数据库连接池最小的连接数目 |
void setInitialPoolSize() | 设置数据库连接池初始化的连接数目 |
Connection getConnection() | 从数据库连接池中获取一个连接 |
当使用C3P0数据源时,首先得创建数据源对象,创建数据源对象可以使用ComboPooledDataSource类,该类有两个构造方法,分别是ComboPooledDataSource()和ComboPooledDataSource(String configName)。
需要注意的是,在使用ComboPooledDataSource(String configName)方法创建数据源对象时必须遵循以下两点:
- (1) 配置文件名称必须为c3p0-config.xml或者c3p0.properties,并且位于该项目的src根目录下。
- (2) 当传入的configName值为空或者不存在时,使用默认配置信息创建数据源。
(2) 通过ComboPooledDataSource类直接创建数据源对象
将c3p0-0.9.5.5.jar、mchange-commons-java-0.2.19.jar 粘贴到 Web\WEB-INF\lib。
cn.ls.Eg03_ls.java。
package cn.ls;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class Eg03_ls {
public static DataSource ds = null;
// 初始化C3P0数据源
static {
ComboPooledDataSource cpds = new ComboPooledDataSource();
// 设置连接数据库需要的配置信息
try {
cpds.setDriverClass("com.mysql.cj.jdbc.Driver");
cpds.setJdbcUrl("jdbc:mysql://101.42.158.247:3306/jdbc_ls?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useSSL=false");
cpds.setUser("root");
cpds.setPassword("***密码***");
// 设置连接池的参数
cpds.setInitialPoolSize(10);
cpds.setMaxPoolSize(15);
ds = cpds;
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static void main(String[] args) throws SQLException {
// 获取数据库连接对象
System.out.println("通过ComboPooledDataSource类直接创建数据源对象【ls】\n"+ds.getConnection());
}
}
运行main方法截图如下:
(3) 通过读取配置文件创建数据源对象
src/c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">
jdbc:mysql://101.42.158.247:3306/jdbc_ls?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useSSL=false
</property>
<property name="user">root</property>
<property name="password">***密码***</property>
<property name="checkoutTimeout">30000</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
</default-config>
<named-config name="dzjiang">
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="jdbcUrl">
jdbc:mysql://101.42.158.247:3306/jdbc_ls?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useSSL=false
</property>
<property name="user">root</property>
<property name="password">***密码***</property>
<property name="initialPoolSize">10</property>
<property name="maxPoolSize">15</property>
</named-config>
</c3p0-config>
cn.ls.Eg04_ls.java。
package cn.ls;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class Eg04_ls {
public static DataSource ds = null;
// 初始化C3P0数据源
static {
// 使用src\c3p0-config.xml配置文件中的default-config节点中name属性的值
ComboPooledDataSource cpds = new ComboPooledDataSource();
ds = cpds;
System.out.println(cpds.getJdbcUrl().toString());
}
public static void main(String[] args) throws SQLException {
System.out.println("使用src\\c3p0-config.xml配置文件的<default-config>节点信息【ls】\n"+ds.getConnection());
}
}
运行main方法截图如下:
cn.ls.Eg05_ls.java
第12行 dzjiang 对应src/c3p0-config.xml第17行定义
package cn.ls;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class Eg05_ls {
public static DataSource ds = null;
// 初始化C3P0数据源
static {
// 使用src\c3p0-config.xml配置文件中的 named-config 节点中name属性的值
ComboPooledDataSource cpds = new ComboPooledDataSource("dzjiang");
ds = cpds;
System.out.println(cpds.getJdbcUrl().toString());
}
public static void main(String[] args) throws SQLException {
System.out.println("使用src\\c3p0-config.xml配置文件的<named-config>节点信息【ls】\n"+ds.getConnection());
}
}
运行main方法截图如下:
2 DBUtils工具
commons-dbutils的核心是两个类和一个接口: DBUtils类、 QueryRunner类、 ResultSetHandler接口
https://commons.apache.org/proper/commons-dbutils/download_dbutils.cgi
2.1 DBUtils工具介绍
DBUtils工具的作用
为了更加简单地使用JDBC,Apache组织提供了一个DBUtils工具,它是操作数据库的一个组件,实现了对JDBC的简单封装,可以在不影响数据库访问性能的情况下简化JDBC的编码工作量。DBUtils工具要有三个作用。
- 写数据,DBUtils可以通过编写SQL语句对数据表进行增、删、改操作。
- 读数据,DBUtils工具可以将从数据表中读取的数据结果集转换成Java常用类集合,以方便对结果进行处理。
- 优化性能,在使用DBUtils工具的基础上,程序可以使用数据源、JNDI、数据库连接池等技术减少代码冗余。
DBUtils的核心类库的三个核心API
2.2 DBUtils类
DBUtils类主要为如关闭连接、装载JDBC驱动程序之类的常规工作提供方法,它提供的方法都是静态方法:
- close()
- closeQuietly(Connection conn,Statement stmt,ResultSet rs)
- commitAndCloseQuietly(Connection conn)
- loadDriver(java.lang.String driverClassName)
方法名称 | 功能描述 |
---|---|
void close(Connection conn) | 当连接不为NULL时,关闭连接 |
void close(Statement stat) | 当声明不为NULL时,关闭声明 |
void close(ResultSet rs) | 当结果集不为NULL时,关闭结果集 |
void closeQuietly(Connection conn) | 当连接不为NULL时,关闭连接,并隐藏一些在程序中抛出的SQL异常 |
void closeQuietly(Statement stat) | 当声明不为NULL时,关闭声明,并隐藏一些在程序中抛出的SQL异常 |
void closeQuietly(ResultSet rs) | 当结果集不为NULL时,关闭结果集,并隐藏一些在程序中抛出的SQL异常 |
void commitAndCloseQuietly(Connection conn) | 提交连接后关闭连接,并隐藏一些在程序中抛出的SQL异常 |
Boolean loadDriver(String driveClassName) | 装载并注册JDBC驱动程序,如果成功就返回true |
2.3 QueryRunner类
QueryRunner类简化了执行SQL语句的代码,它与ResultSetHandler组合在一起就能完成大部分的数据库操作,大大减少编码量。针对不同的数据库操作,QueryRunner类提供的不同的方法。
- update(Connection conn, String sql)
- update(Connection conn, String sql, Object[] params)
- query(String sql, ResultSetHandler rsh, Object[] params)
- query(Connection conn, String sql, ResultSetHandler rsh)
- query(Connection conn, String sql, ResultSetHandler rsh, Object[] params)
QueryRunner类的常用方法
方法名称 | 功能描述 |
---|---|
Object query(Connection conn,String sql,ResultSetHandler rsh,Object[] params) | 执行查询操作,传入的Connection对象不能为空 |
Object query (String sql, ResultSetHandler rsh,Object[] params) | 执行查询操作 |
Object query (Connection conn,String sql, ResultSetHandler rsh) | 执行一个不需要置换参数的查询操作 |
int update(Connection conn, String sql, ResultSetHandler rsh) | 执行一个更新(插入、删除、更新)操作 |
int update(Connection conn, String sql) | 执行一个不需要置换参数的更新操作 |
int batch(Connection conn,String sql, Object[] []params) | 批量添加、修改、删除 |
int batch(String sql, Object[][] params) | 批量添加、修改、删除 |
2.4 ResultSetHandler接口
ResultSetHandler接口用于处理ResultSet结果集,它可以将结果集中的数据转换为不同的形式。根据结果集中不同的数据类型,ResultSetHandler提供了几种常见的实现类。
- BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
- BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,并存放到List里。
- ColumnListHandler:将某列属性的值封装到List集合中。
- ScalarHandler:将结果集中某一条记录的某一列数据----某个标量存储成Object对象。
类名称 | 功能描述 |
---|---|
AbstractKeyedHandler | 该类为抽象类,能够把结果集里面的数据转换为用Map存储。 |
AbstractListHandler | 该类为抽象类,能够把结果集里面的数据转换为用List存储 |
ArrayHandler | 把结果集中的第一行数据转成对象数组。 |
ArrayListHandler | 把结果集中的每一行数据都转成一个对象数组,再将数组存放到List中。 |
BaseResultSetHandler | 把结果集转换成其他对象的扩展。 |
BeanHandler | 将结果集中的第一行数据封装到一个对应的JavaBean实例中。 |
BeanListHandler | 将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。 |
BeanMapHandler | 将结果集中的每一行数据都封装到一个对应的JavaBean实例中,然后再根据指定的key把每个JavaBean再存放到一个Map里。 |
ColumnListHandler | 将结果集中某一列的数据存放到List中。 |
KeyedHandler | 将结果集中的每一行数据都封装到一个Map里,然后再根据指定的key把每个Map再存放到一个Map里。 |
MapHandler | 将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。 |
MapListHandler | 将结果集中的每一行数据都封装到一个Map里,然后再存放到List中。 |
ScalarHandler | 将结果集中某一条记录的其中某一列的标量数据存储成Object对象。 |
2.5 ResultSetHandler实现类
(1) BeanHandler和BeanListHandler
类名称 | 相同点 | 不同点 |
---|---|---|
BeanHandler | 都要先将结果集封装进JavaBean | 封装单条数据,把结果集的第一条数据的字段放入一个JavaBean中 |
BeanListHandler | 封装多条数据,把每条数据的字段值各放入一个JavaBean中,再把所有JavaBean都放入List集合中 |
(a) MySQL 数据表
# 下面表已经在上一章创建
create database jdbc_ls DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_chinese_ci;
use jdbc_ls;
CREATE TABLE 用户表(
id INT PRIMARY KEY AUTO_INCREMENT,
用户名 VARCHAR(40),
密码 VARCHAR(40),
电邮 VARCHAR(60),
生日 DATE
)CHARACTER SET utf8 COLLATE utf8_general_ci;
INSERT INTO 用户表(用户名,密码,电邮,生日) VALUES
('ls','1234560','ls@sina.com','1963-12-01'),
('张三','1234561','zs@sina.com','1980-12-02'),
('李四','1234562','lisi@sina.com','1981-12-03'),
('王五','1234563','wangwu@sina.com','1979-12-04');
/*为了查看数据是否添加成功,使用SELECT语句查询users表,SQL语句如下所示*/
SELECT * FROM 用户表;
commons-dbutils-1.7.jar粘贴到 Web - WEB-INF - lib。
(b) cn.ls.c3p0.javabean.User
package cn.ls.c3p0.javabean;
public class User {
private int id;
private String 用户名;
private String 密码;
private String 电邮;
private Date 生日;
// setter | getter
//toString
}
(c) src创建包cn.ls.jdbc.utils,创建JDBCUtils.java
package cn.ls.jdbc.utils;
import java.sql.*;
public class JDBCUtils {
// 加载驱动,并建立数据库连接
public static Connection getConnection() throws SQLException,
ClassNotFoundException {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://101.42.158.247:3306/jdbc_ls?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useSSL=false";
String username = "root";
String password = "*********";
Connection conn = DriverManager.getConnection(url, username,
password);
return conn;
}
// 关闭数据库连接,释放资源
public static void release(Statement stmt, Connection conn) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
public static void release(ResultSet rs, Statement stmt,
Connection conn){
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
release(stmt, conn);
}
}
(d) 在cn.ls.jdbc.dao 创建BaseDao.java
package cn.ls.jdbc.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.commons.dbutils.ResultSetHandler;
import cn.ls.utils.JDBCUtils;
public class BaseDao {
// 优化查询
public static Object query(String sql, ResultSetHandler<?> rsh,
Object... params) throws SQLException {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
// 获得连接
conn = JDBCUtils.getConnection();
// 预编译sql
pstmt = conn.prepareStatement(sql);
// 将参数设置进去
for (int i = 0; params != null && i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
// 发送sql
rs = pstmt.executeQuery();
// 让调用者去实现对结果集的处理
Object obj = rsh.handle(rs);
return obj;
} catch (Exception e) {
e.printStackTrace();
}finally {
// 释放资源
JDBCUtils.release(rs, pstmt, conn);
}
return rs;
}
}
(e) cn.ls.jdbc创建ResultSetTest1_ls.java。演示BeanHandler类处理结果集。
package cn.ls.jdbc;
import java.sql.SQLException;
import cn.ls.jdbc.dao.BaseDao;
import cn.ls.c3p0.javabean.User;
import org.apache.commons.dbutils.handlers.BeanHandler;
public class ResultSetTest1_ls {
public static void testBeanHandler() throws SQLException {
BaseDao basedao = new BaseDao();
String sql = "select * from 用户表 where id=?";
User user = (User) basedao.query(sql,
new BeanHandler(User.class), 1);
System.out.println("演示BeanHandler类处理结果集【ls】");
System.out.println("id为1的User对象的【用户名】值为:" + user.get用户名());
System.out.println("id为1的User对象为:" + user.toString());
}
public static void main(String[] args) throws SQLException {
testBeanHandler();
}
}
运行main方法截图如下:
(f) cn.ls.Test_ls.java 添加下列测试程序段
package cn.ls.jdbc;
import java.sql.SQLException;
import java.util.ArrayList;
import cn.ls.c3p0.javabean.User;
import cn.ls.jdbc.dao.BaseDao;
import org.apache.commons.dbutils.handlers.BeanListHandler;
public class ResultSetTest2_ls {
public static void testBeanListHandler() throws SQLException {
BaseDao basedao = new BaseDao();
String sql = "select * from 用户表 ";
ArrayList<User> list = (ArrayList<User>) basedao.query(sql,
new BeanListHandler(User.class));
System.out.println("演示BeanListHandler类处理结果集【ls】");
for (int i = 0; i < list.size(); i++) {
System.out.println("第" + (i + 1) + "条数据的username值为:"
+ list.get(i).get用户名());
}
System.out.println("---------------------------------------------");
for (int i = 0; i < list.size(); i++) {
System.out.println("第" + (i + 1) + "条数据:"
+ list.get(i).toString());
}
}
public static void main(String[] args) throws SQLException {
testBeanListHandler();
}
}
运行main方法截图如下:
(2) ColumnListHandler和ScalarHandler
(a) cn.ls.jdbc.ResultSetTest3_ls.java
package cn.ls.jdbc;
import java.sql.SQLException;
import cn.ls.jdbc.dao.BaseDao;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
public class ResultSetTest3_ls {
public static void testColumnListHandler() throws SQLException {
BaseDao basedao = new BaseDao();
String sql = "select * from 用户表";
Object arr = (Object) basedao.query(sql,
new ColumnListHandler("用户名"));
System.out.println("演示ColumnListHandler类的使用方法【ls】");
System.out.println("用户名:" +arr);
}
public static void main(String[] args) throws SQLException {
testColumnListHandler();
}
}
运行main方法截图如下:
(b) cn.ls.jdbc.ResultSetTest4_ls.java
package cn.ls.jdbc;
import java.sql.SQLException;
import cn.ls.jdbc.dao.BaseDao;
import org.apache.commons.dbutils.handlers.ScalarHandler;
public class ResultSetTest4_ls {
public static void testScalarHandler() throws SQLException {
BaseDao basedao = new BaseDao();
String sql = "select * from 用户表 where id=?";
Object obj = (Object) basedao.query(sql,
new ScalarHandler("用户名"), 1);
System.out.println("演示ScalarHandler类的使用方法【ls】");
System.out.println(obj);
}
public static void main(String[] args) throws SQLException {
testScalarHandler();
}
}
运行main方法截图如下:
2.6 动手实践:使用DBUtils实现增删改查
(1) cn.ls.c3p0.utils C3p0Utils.java
package cn.ls.c3p0.utils;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class C3p0Utils {
private static DataSource ds;
static {
ds = new ComboPooledDataSource();
}
public static DataSource getDataSource() {
return ds;
}
}
(2) cn.ls.c3p0.dao.QueryDao_ls.java
package cn.ls.c3p0.dao;
import cn.ls.c3p0.javabean.User;
import cn.ls.c3p0.utils.C3p0Utils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import java.sql.SQLException;
import java.util.List;
public class QueryDao_ls {
public static void main(String[] args)throws SQLException {
// 创建QueryRunner对象
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());
// 写SQL语句
String sql = "select * from 用户表 where id=2";
// 调用方法
User user1 = (User) runner.query(sql,new BeanHandler(User.class));
System.out.println("id=2 "+user1.toString());
System.out.println("---------------------------------");
// 写SQL语句
sql = "select * from 用户表";
// 调用方法
List<User> list = (List) runner.query(sql,new BeanListHandler(User.class));
for(User user : list){
System.out.println(user.toString());
}
}
}
运行main方法截图如下:
(3) cn.ls.c3p0.dao.InsertDao_ls.java
package cn.ls.c3p0.dao;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import cn.ls.c3p0.utils.C3p0Utils;
public class InsertDao_ls {
public static void main(String[] args)throws SQLException{
// 创建QueryRunner对象
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());
String sql = "insert into 用户表 (id,用户名,密码,电邮,生日) values (7,'孙七','1234567','孙七@139.com','2001-01-07')";
int num = runner.update(sql);
if (num > 0){
System.out.println("添加【孙七】成功!----【ls】");
}else{
System.out.println("添加【孙七】失败!----【ls】");
}
}
}
运行main方法截图如下:
(4) cn.ls.c3p0.dao.UpdateDao_ls.java
package cn.ls.c3p0.dao;
import cn.ls.c3p0.utils.C3p0Utils;
import org.apache.commons.dbutils.QueryRunner;
import java.sql.SQLException;
public class UpdateDao_ls {
public static void main(String[] args)throws SQLException {
// 创建QueryRunner对象
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());
// 写SQL语句
String sql = "update 用户表 set 用户名='孙小七',密码='7777777' where 用户名='孙七'";
// 调用方法
int num = runner.update(sql);
if (num > 0){
System.out.println("修改[孙七]成功!---- 【ls】");
}else{
System.out.println("修改[孙七]失败!---- 【ls】");
}
}
}
运行main方法截图如下:
(5) cn.ls.c3p0.dao.DeleteDao_ls.java
package cn.ls.c3p0.dao;
import cn.ls.c3p0.utils.C3p0Utils;
import org.apache.commons.dbutils.QueryRunner;
import java.sql.SQLException;
public class DeleteDao_ls {
public static void main(String[] args)throws SQLException {
// 创建QueryRunner对象
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());
// 写SQL语句
String sql = "delete from 用户表 where 用户名='赵六'";
// 调用方法
int num = runner.update(sql);
if (num > 0){
System.out.println("删除[赵六]成功!----【ls】");
}else{
System.out.println("删除[赵六]失败!----【ls】");
}
}
}
运行main方法截图如下:
愿者可参阅《JavaWeb程序开发进阶》:
- http://www.lszhaojiang.cn/index_javaweb.html
- ch1 JDBC入门 例题
- ch2 JDBC事务与连接池
- ch3 DBUtils工具