Java基础-DButils工具类(QueryRunner)详解
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils。DBUtils就是JDBC的简化开发工具包。需要项目导入commons-dbutils-1.7.jar才能够正常使用DBUtils工具。安装方式可参考:“http://www.cnblogs.com/yinzhengjie/p/9017416.html”
一.DBUtils工具类介绍
DBUtils是java编程中的数据库操作实用工具,小巧简单实用。DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码。Dbutils三个核心功能介绍
1>. QueryRunner中提供对sql语句(insert,update,delete)操作的API;
2>.ResultSetHandler接口,用于定义select操作后,怎样封装结果集.;
3>.DbUtils类,它就是一个工具类,定义了关闭资源与事务处理的方法;
二.QueryRunner类使用方法
update(Connection conn, String sql, Object... params) ,用来完成表数据的增加、删除、更新操作;
query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) ,用来完成表数据的查询操作;
1>.准备实验环境
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A/
EMAIL:y1053419035@qq.com
*/ #创建表结构
create table Classmate(
ID int(11) NOT NULL primary key AUTO_INCREMENT,
Name varchar(30) COLLATE gbk_bin DEFAULT NULL,
Age int DEFAULT NULL,
Job varchar(50),
Chinese int,
English int,
Math int,
Physics int,
Chemistry int,
Biology int
); #往表里添加数据
insert into Classmate values(null,'王建军',30,'Java讲师',100,98,99,96,97,100);
insert into Classmate values(null,'常庆林',28,'Linux讲师',100,100,98,93,99,96);
insert into Classmate values(null,'徐培成',35,'BigData讲师',100,100,100,98,96,100);
insert into Classmate values(null,'李永强',30,'javaEE开发工程师',100,93,91,74,89,100);
insert into Classmate values(null,'赵子昂',24,'python开发工程师',98,93,91,74,89,100);
insert into Classmate values(null,'桂阳',25,'C++开发工程师',100,98,93,91,99,82);
insert into Classmate values(null,'肖云龙',24,'Golang开发工程师',93,97,85,100,93,69);
insert into Classmate values(null,'李洋',23,'C#开发工程师',100,98,99,96,97,100);
insert into Classmate values(null,'卜孟龙',30,'BigData开发',98,93,100,100,73,92);
insert into Classmate values(null,'罗大鹏',22,'Java开发工程师',100,84,91,87,100,93);
insert into Classmate values(null,'尹正杰',26,'高级运维工程师',100,100,100,100,100,100);
2>.QueryRunnerd的update方法实现增(insert),删(delete),改(update)
DriverName=com.mysql.jdbc.Driver
#zai "url" lu jing hou jia "?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true" ke yi kai qi pi chu li mo shi !
url=jdbc:mysql://192.168.0.254:5200/yinzhengjie?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true
username=root
password=yinzhengjie
config.properties.java 文件内容
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.note2; import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties; /*
* 编写数据库连接的工具类,JDBC工具类
* 获取连接对象采用读取配置文件方式
* 读取文件获取连接,执行一次,static{}
*/
public class Utils {
private static Connection con ;
private static String DriverName;
private static String url;
private static String username;
private static String password; static{
try{
readConfig();
Class.forName(DriverName);
con = DriverManager.getConnection(url, username, password);
}catch(Exception ex){
throw new RuntimeException("数据库连接失败");
}
} private static void readConfig()throws Exception{
//注意!想要使用"config.properties"这个配置文件,就必须将该文件放在src目录下,也就是说要跟你的包名在同一个目录下哟,或者说是在classpath路径下也可以!
InputStream in = Utils.class.getClassLoader().getResourceAsStream("config.properties");
Properties pro = new Properties();
pro.load(in);
DriverName=pro.getProperty("DriverName");
url = pro.getProperty("url");
username = pro.getProperty("username");
password = pro.getProperty("password");
} public static Connection getConnection(){
return con;
} }
Utils.java 文件内容
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ package cn.org.yinzhengjie.note2; import java.sql.Connection;
import java.sql.SQLException; import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner; /*
* 使用QueryRunner类,实现对数据表的
* insert delete update
* 调用QueryRunner类的方法 update (Connection con,String sql,Object...param)
* Object...param 可变参数,Object类型,SQL语句会出现?占位符
* 数据库连接对象,自定义的工具类传递
*/
public class QueryRunnerDemo {
private static Connection conn = Utils.getConnection();
public static void main(String[] args)throws SQLException {
// insert();
// update();
delete();
}
/*
* 定义方法,使用QueryRunner类的方法delete将数据表的数据删除
*/
public static void delete()throws SQLException{
//创建QueryRunner类对象
QueryRunner qr = new QueryRunner();
//写删除的SQL语句
String sql = "DELETE FROM classmate WHERE id<=?";
//调用QueryRunner方法update
int row = qr.update(conn, sql, 10);
System.out.printf("已经有[%d]发生了改变",row);
/*
* 判断insert,update,delete执行是否成功
* 对返回值row判断
* if(row>0) 执行成功
*/
DbUtils.closeQuietly(conn);
} /*
* 定义方法,使用QueryRunner类的方法update将数据表的数据修改
*/
public static void update()throws SQLException{
//创建QueryRunner类对象
QueryRunner qr = new QueryRunner();
//写修改数据的SQL语句
String sql = "UPDATE classmate SET age=? WHERE name=?";
//定义Object数组,存储?中的参数,注意传入的位置哟,不要把顺序写反了!
Object[] params = {18,"尹正杰"};
//调用QueryRunner方法update
int row = qr.update(conn, sql, params);
System.out.printf("已经有[%d]发生了改变",row);
DbUtils.closeQuietly(conn);
} /*
* 定义方法,使用QueryRunner类的方法update向数据表中,添加数据
*/
public static void insert()throws SQLException{
//创建QueryRunner类对象
QueryRunner qr = new QueryRunner();
String sql = "INSERT INTO classmate VALUES(?,?,?,?,?,?,?,?,?,?)";
//将三个?占位符的实际参数,写在数组中
Object[] params = {null,"方合意",24,"python开发工程师",100,60,89,94,92,87};
//调用QueryRunner类的方法update执行SQL语句
System.out.println(conn);
int row = qr.update(conn, sql, params);
System.out.printf("已经有[%d]发生了改变",row);
DbUtils.closeQuietly(conn);
}
}
3>.QueryRunnerd的query方法实现查(select)
ResultSetHandler结果集处理类如下:
ArrayHandler |
将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值 |
ArrayListHandler |
将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。 |
BeanHandler |
将结果集中第一条记录封装到一个指定的javaBean中。 |
BeanListHandler |
将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中 |
ColumnListHandler |
将结果集中指定的列的字段值,封装到一个List集合中 |
ScalarHandler |
它是用于单数据。例如select count(*) from 表操作。 |
MapHandler |
将结果集第一行封装到Map集合中,Key 列名, Value 该列数据 |
MapListHandler |
将结果集第一行封装到Map集合中,Key 列名, Value 该列数据,Map集合存储到List集合 |
接下来我们一起对上面的八种方法进行一一举例,测试代码如下:
DriverName=com.mysql.jdbc.Driver
#zai "url" lu jing hou jia "?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true" ke yi kai qi pi chu li mo shi !
url=jdbc:mysql://192.168.0.254:5200/yinzhengjie?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true
username=root
password=yinzhengjie
config.properties.java 文件内容
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.note2; import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties; /*
* 编写数据库连接的工具类,JDBC工具类
* 获取连接对象采用读取配置文件方式
* 读取文件获取连接,执行一次,static{}
*/
public class Utils {
private static Connection con ;
private static String DriverName;
private static String url;
private static String username;
private static String password; static{
try{
readConfig();
Class.forName(DriverName);
con = DriverManager.getConnection(url, username, password);
}catch(Exception ex){
throw new RuntimeException("数据库连接失败");
}
} private static void readConfig()throws Exception{
//注意!想要使用"config.properties"这个配置文件,就必须将该文件放在src目录下,也就是说要跟你的包名在同一个目录下哟,或者说是在classpath路径下也可以!
InputStream in = Utils.class.getClassLoader().getResourceAsStream("config.properties");
Properties pro = new Properties();
pro.load(in);
DriverName=pro.getProperty("DriverName");
url = pro.getProperty("url");
username = pro.getProperty("username");
password = pro.getProperty("password");
} public static Connection getConnection(){
return con;
} }
Utils.java 文件内容
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ package cn.org.yinzhengjie.note2; public class Student {
private int ID;
private String Name;
private int Age;
private String Job;
private int Chinese;
private int English;
private int Math;
private int Physics;
private int Chemistry;
private int Biology;
public Student(int iD, String name, int age, String job, int chinese, int english, int math, int physics,int chemistry, int biology) {
super();
ID = iD;
Name = name;
Age = age;
Job = job;
Chinese = chinese;
English = english;
Math = math;
Physics = physics;
Chemistry = chemistry;
Biology = biology;
}
public Student() {
super();
}
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public int getAge() {
return Age;
}
public void setAge(int age) {
Age = age;
}
public String getJob() {
return Job;
}
public void setJob(String job) {
Job = job;
}
public int getChinese() {
return Chinese;
}
public void setChinese(int chinese) {
Chinese = chinese;
}
public int getEnglish() {
return English;
}
public void setEnglish(int english) {
English = english;
}
public int getMath() {
return Math;
}
public void setMath(int math) {
Math = math;
}
public int getPhysics() {
return Physics;
}
public void setPhysics(int physics) {
Physics = physics;
}
public int getChemistry() {
return Chemistry;
}
public void setChemistry(int chemistry) {
Chemistry = chemistry;
}
public int getBiology() {
return Biology;
}
public void setBiology(int biology) {
Biology = biology;
}
@Override
public String toString() { return "ID="+ID+", 姓名="+Name+", 年龄="+Age+", 工作="+Job+", 语文="+Chinese+", 英语="+English+", 数学="+Math+", 物理="+Physics+", 化学="+Chemistry+", 生物="+Biology;
} }
Student.java 文件内容
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
EMAIL:y1053419035@qq.com
*/ package cn.org.yinzhengjie.note2; import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map; 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.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler; /*
* QueryRunner数据查询操作:
* 调用QueryRunner类方法query(Connection con,String sql,ResultSetHandler r, Object..params)
* ResultSetHandler r 结果集的处理方式,传递ResultSetHandler接口实现类
* Object..params SQL语句中的?占位符
*
* 注意: query方法返回值,返回的是T 泛型, 具体返回值类型,跟随结果集处理方式变化
*/
public class QueryRunnerDemo1 {
private static Connection con = Utils.getConnection();
public static void main(String[] args) throws SQLException{
// arrayHandler();
// arrayListHandler();
// beanHandler();
// beanListHander();
// columnListHandler();
// scalarHandler();
// mapHandler();
mapListHandler();
}
/*
* 结果集第一种处理方法, ArrayHandler,不推荐使用!
* 将结果集的第一行存储到对象数组中 Object[]
*/
public static void arrayHandler()throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT * FROM classmate";
//调用方法query执行查询,传递连接对象,SQL语句,结果集处理方式的实现类
//返回对象数组
Object[] result = qr.query(con, sql, new ArrayHandler());
for(Object obj : result){
System.out.print(obj);
}
} /*
* 结果集第二种处理方法,ArrayListHandler
* 将结果集的每一行,封装到对象数组中, 出现很多对象数组
* 对象数组存储到List集合
*/
public static void arrayListHandler()throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT * FROM classmate";
//调用query方法,结果集处理的参数上,传递实现类ArrayListHandler
//方法返回值 每行是一个对象数组,存储到List
List<Object[]> result= qr.query(con, sql, new ArrayListHandler()); //集合的遍历
for( Object[] objs : result){
//遍历对象数组
for(Object obj : objs){
System.out.print(obj+",");
}
System.out.println();
}
} /*
* 结果集第三种处理方法,BeanHandler
* 将结果集的第一行数据,封装成JavaBean对象
* 注意: 被封装成数据到JavaBean对象, Sort类必须有空参数构造
*/
public static void beanHandler()throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT * FROM classmate";
//调用方法,传递结果集实现类BeanHandler
//BeanHandler(Class<T> type)
Student s = qr.query(con, sql, new BeanHandler<Student>(Student.class));
System.out.println(s);
} /*
* 结果集第四种处理方法, BeanListHandler
* 结果集每一行数据,封装JavaBean对象
* 多个JavaBean对象,存储到List集合
*/
public static void beanListHander()throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT * FROM classmate ";
//调用方法query,传递结果集处理实现类BeanListHandler
List<Student> list = qr.query(con, sql, new BeanListHandler<Student>(Student.class));
for(Student s : list){
System.out.println(s);
}
} /*
* 结果集第五种处理方法,ColumnListHandler
* 结果集,指定列的数据,存储到List集合
* List<Object> 每个列数据类型不同
*/
public static void columnListHandler()throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT * FROM classmate ";
//调用方法 query,传递结果集实现类ColumnListHandler
//实现类构造方法中,使用字符串的列名
List<Object> list = qr.query(con, sql, new ColumnListHandler<Object>("name"));
for(Object obj : list){
System.out.println(obj);
}
} /*
* 结果集第六种处理方法,ScalarHandler
* 对于查询后,只有1个结果
*/
public static void scalarHandler()throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT COUNT(*) FROM classmate";
//调用方法query,传递结果集处理实现类ScalarHandler
long count = qr.query(con, sql, new ScalarHandler<Long>());
System.out.println(count);
} /*
* 结果集第七种处理方法,MapHandler
* 将结果集第一行数据,封装到Map集合中
* Map<键,值> 键:列名 值:这列的数据
*/
public static void mapHandler()throws SQLException{
QueryRunner qr = new QueryRunner();
//注意,这里是可以用占位符哟,我下面就对他进行了传参,参数为11
String sql = "SELECT * FROM classmate where id = ?";
//调用方法query,传递结果集实现类MapHandler
//返回值: Map集合,Map接口实现类, 泛型
Map<String,Object> map = qr.query(con, sql, new MapHandler(),);
//遍历Map集合
for(String key : map.keySet()){
System.out.println(key+".."+map.get(key));
}
} /*
* 结果集第八种处理方法,MapListHandler
* 将结果集每一行存储到Map集合,键:列名,值:数据
* Map集合过多,存储到List集合
*/
public static void mapListHandler()throws SQLException{
QueryRunner qr = new QueryRunner();
String sql = "SELECT * FROM classmate";
//调用方法query,传递结果集实现类MapListHandler
//返回值List集合, 存储的是Map集合
List<Map<String,Object>> list = qr.query(con, sql, new MapListHandler());
//遍历集合list
for( Map<String,Object> map : list ){
for(String key : map.keySet()){
System.out.print(key+"..."+map.get(key)+", ");
}
System.out.println();
} }
}