之前我们简单的写了数据库工具类,接下来学习一下第三方优秀的架包。
Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。DbUtils是Apache组织封装的工具类!
DBUtils是java编程中的数据库操作实用工具,小巧简单实用,
①.对于数据表的读操作,他可以把结果转换成List,Array,Set等java集合,便于程序员操作;
②.对于数据表的写操作,也变得很简单(只需写sql语句)
③.可以使用数据源,数据库连接池等技术来优化性能--重用已经构建好的数据库连接对象,而不像php,asp那样,费时费力的不断重复的构建和析构这样的对象。
DBUtils里面有几个很重要的类和接口:QueryRunner类、ResultSetHandler接口
QueryRunner类使用详解:
该类简单化了SQL查询,它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。
QueryRunner类提供了两个构造方法:
Ⅰ默认的构造方法
Ⅱ需要一个 javax.sql.DataSource 来作参数的构造方法。
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)
ResultSetHandler接口的实现类:
Ⅰ、ArrayHandler:把结果集中的第一行数据转成对象数组。
Ⅱ、ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
Ⅲ、BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
Ⅳ、BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
Ⅴ、ColumnListHandler:将结果集中某一列的数据存放到List中。
Ⅵ、KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
Ⅶ、MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
Ⅷ、MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
下面通过代码来学习一下用法,这里使用了C3P0数据库连接池,首先建立数据库:
CREATE TABLE `students` (
`sid` varchar(8) NOT NULL,
`sname` varchar(255) DEFAULT NULL,
`gender` varchar(255) DEFAULT NULL,
`birthday` date DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
PRIMARY KEY (`sid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
建立Student实体类:
import java.util.Date;
public class Student {
private String sid;
private String sname;
private String gender;
private Date birthday;
private String address;
public Student() {
}
public Student(String sid, String sname, String gender, Date birthday, String address) {
this.sid = sid;
this.sname = sname;
this.gender = gender;
this.birthday = birthday;
this.address = address;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Student{" +
"sid='" + sid + '\'' +
", sname='" + sname + '\'' +
", gender='" + gender + '\'' +
", birthday=" + birthday +
", address='" + address + '\'' +
'}';
}
}
配置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://localhost:3306/test?characterEncoding=utf-8
</property>
<property name="user">root</property>
<property name="password">1234</property>
<!--扩展配置 -->
<!-- 连接超过30秒报错 -->
<property name="checkoutTimeout">30000</property>
<!--30秒检查空闲连接 -->
<property name="idleConnectionTestPeriod">30</property>
<!-- 初始化连接对象的数目 -->
<property name="initialPoolSize">10</property>
<!-- 30秒不适用丢弃 -->
<property name="maxIdleTime">30</property>
<!-- 数据库连接池最大连接数100 -->
<property name="maxPoolSize">100</property>
<!-- 数据库最小连接数 -->
<property name="minPoolSize">10</property>
</default-config>
<!-- 命名的配置 -->
<named-config name="oracle">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/bookdb</property>
<property name="user">root</property>
<property name="password">123</property>
<!-- 如果池中数据连接不够时一次增长多少个 -->
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">20</property>
<property name="minPoolSize">10</property>
<property name="maxPoolSize">40</property>
</named-config>
</c3p0-config>
创建C3P0工具类:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class C3P0Utils {
// 默认会读取类路径下一个配置文件叫:c3p0-config.xml
private static ComboPooledDataSource datasource = new ComboPooledDataSource();
public static DataSource getDadaSource(){
return datasource;
}
public static Connection getConnection() {
try {
return datasource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
// 关闭资源
public static void close(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(PreparedStatement st) {
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(ResultSet set) {
if (set != null) {
try {
set.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(Connection conn, PreparedStatement st, ResultSet rt) {
close(conn);
close(st);
close(rt);
}
}
进行数据库的各种操作:
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.*;
import org.junit.Test;
import java.sql.SQLException;
import java.util.*;
public class DBUtilsTest {
//增加操作
@Test
public void testadd() throws Exception {
Student b = new Student("S0000009", "李刚", "男",new Date(), "三亚");
QueryRunner rq = new QueryRunner(C3P0Utils.getDadaSource());
Object params[] = { b.getSid(), b.getSname(), b.getGender(), b.getBirthday(), b.getAddress() };
int count = rq.update("insert into students values(?,?,?,?,?)", params);
System.out.println(count > 0 ? "成功" : "失败");
}
//查询全部数据操作
@Test
public void testQuery() throws Exception {
String sql = "select * from students";
QueryRunner rq = new QueryRunner(C3P0Utils.getDadaSource());
List<Student> list = rq.query(sql, new BeanListHandler<Student>(Student.class));
for (Student b : list) {
System.out.println(b);
}
}
//删除数据操作
@Test
public void testDelete() throws Exception{
QueryRunner rq = new QueryRunner(C3P0Utils.getDadaSource());
Object[] params = {"S0000009"};
int count = rq.update("delete from students where sid=?",params);
System.out.println(count>0?"删除成功":"删除失败");
}
//更新数据库操作
@Test
public void testupdate() throws Exception {
Student b = new Student("S0000008","韩梅梅","男",new Date(),"哈尔滨");
QueryRunner rq = new QueryRunner(C3P0Utils.getDadaSource());
Object[] params = { b.getSname(), b.getGender(), b.getBirthday(), b.getAddress(),b.getSid() };
int count = rq.update("update students set sname=?,gender=?,birthday=?,address=? where sid=?", params);
System.out.println(count > 0 ? "成功" : "失败");
}
/*
* 查询多条数据封装为一个集合
*/
@Test
public void testManyQuery() throws Exception {
String sql = "select * from students";
QueryRunner rq = new QueryRunner(C3P0Utils.getDadaSource());
// BeanListHandler 把查询的数据封装为一个对象 并把对象装载到list集合中!
List<Student> list = rq.query(sql, new BeanListHandler<Student>(Student.class));
for (Student s : list) {
System.out.println(s);
}
}
/*
* 查询一个对象
*/
@Test
public void testGetById() throws SQLException {
String sql = "select * from students where sid=?";
QueryRunner rq = new QueryRunner(C3P0Utils.getDadaSource());
Object[] params = { "S0000004" };
Student s = rq.query(sql, new BeanHandler<Student>(Student.class), params);
System.out.println(s);
}
/*
* 把结果集中的第一行数据转成对象数组。
*/
@Test
public void test1() throws Exception{
QueryRunner rq = new QueryRunner(C3P0Utils.getDadaSource());
String sql = "select * from students";
Object[] arrays = rq.query(sql,new ArrayHandler());
System.out.println(Arrays.toString(arrays));
}
/*
* ?把结果集中的每一行数据都转成一个数组,再存放到List中。
*/
@Test
public void test2() throws Exception{
QueryRunner rq = new QueryRunner(C3P0Utils.getDadaSource());
String sql = "select * from students";
List<Object[]> arrays = rq.query(sql,new ArrayListHandler());
for (Object[] o : arrays) {
System.out.println(Arrays.toString(o));
}
}
/*
* ColumnListHandler:将结果集中某一列的数据存放到List中
*/
@Test
public void test3() throws Exception{
QueryRunner rq = new QueryRunner(C3P0Utils.getDadaSource());
String sql = "select sname from students";
List<String> names = rq.query(sql,new ColumnListHandler<String>("sname"));
for (String s : names) {
System.out.println(s);
}
}
/*
* ?KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
*/
@Test
public void test4() throws Exception{
QueryRunner rq = new QueryRunner(C3P0Utils.getDadaSource());
String sql = "select * from students";
Map<String, Map<String, Object>> map = rq.query(sql,new KeyedHandler<String>("sid"));
Set<Map.Entry<String, Map<String, Object>>> entrySet = map.entrySet();
for (Map.Entry<String, Map<String, Object>> entry : entrySet) {
String key = entry.getKey(); //SID
Map<String, Object> map2 = entry.getValue();
Set<Map.Entry<String, Object>> entrySet2 = map2.entrySet();
for (Map.Entry<String, Object> entry2 : entrySet2) {
String k1 = entry2.getKey();
Object v1 = entry2.getValue();
System.out.println(k1+"---"+v1);
}
System.out.println("---------------------------");
}
}
/*
* MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
*/
@Test
public void test5() throws Exception{
QueryRunner qr = new QueryRunner(C3P0Utils.getDadaSource());
String sql1 = "select * from students";
List<Map<String, Object>> list = qr.query(sql1,new MapListHandler());
for (Map<String, Object> m : list) {
Set<Map.Entry<String, Object>> e = m.entrySet();
for (Map.Entry<String, Object> entry : e) {
String key = entry.getKey();
Object value = entry.getValue();
System.out.println(key+"---"+value);
}
System.out.println("-----------------------------------");
}
}
}