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>.准备实验环境
1 /* 2 @author :yinzhengjie 3 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/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 8 #创建表结构 9 create table Classmate( 10 ID int(11) NOT NULL primary key AUTO_INCREMENT, 11 Name varchar(30) COLLATE gbk_bin DEFAULT NULL, 12 Age int DEFAULT NULL, 13 Job varchar(50), 14 Chinese int, 15 English int, 16 Math int, 17 Physics int, 18 Chemistry int, 19 Biology int 20 ); 21 22 #往表里添加数据 23 insert into Classmate values(null,'王建军',30,'Java讲师',100,98,99,96,97,100); 24 insert into Classmate values(null,'常庆林',28,'Linux讲师',100,100,98,93,99,96); 25 insert into Classmate values(null,'徐培成',35,'BigData讲师',100,100,100,98,96,100); 26 insert into Classmate values(null,'李永强',30,'javaEE开发工程师',100,93,91,74,89,100); 27 insert into Classmate values(null,'赵子昂',24,'python开发工程师',98,93,91,74,89,100); 28 insert into Classmate values(null,'桂阳',25,'C++开发工程师',100,98,93,91,99,82); 29 insert into Classmate values(null,'肖云龙',24,'Golang开发工程师',93,97,85,100,93,69); 30 insert into Classmate values(null,'李洋',23,'C#开发工程师',100,98,99,96,97,100); 31 insert into Classmate values(null,'卜孟龙',30,'BigData开发',98,93,100,100,73,92); 32 insert into Classmate values(null,'罗大鹏',22,'Java开发工程师',100,84,91,87,100,93); 33 insert into Classmate values(null,'尹正杰',26,'高级运维工程师',100,100,100,100,100,100);
2>.QueryRunnerd的update方法实现增(insert),删(delete),改(update)

1 DriverName=com.mysql.jdbc.Driver 2 #zai "url" lu jing hou jia "?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true" ke yi kai qi pi chu li mo shi ! 3 url=jdbc:mysql://192.168.0.254:5200/yinzhengjie?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true 4 username=root 5 password=yinzhengjie

1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.note2; 7 8 import java.io.InputStream; 9 import java.sql.Connection; 10 import java.sql.DriverManager; 11 import java.util.Properties; 12 13 /* 14 * 编写数据库连接的工具类,JDBC工具类 15 * 获取连接对象采用读取配置文件方式 16 * 读取文件获取连接,执行一次,static{} 17 */ 18 public class Utils { 19 private static Connection con ; 20 private static String DriverName; 21 private static String url; 22 private static String username; 23 private static String password; 24 25 static{ 26 try{ 27 readConfig(); 28 Class.forName(DriverName); 29 con = DriverManager.getConnection(url, username, password); 30 }catch(Exception ex){ 31 throw new RuntimeException("数据库连接失败"); 32 } 33 } 34 35 private static void readConfig()throws Exception{ 36 //注意!想要使用"config.properties"这个配置文件,就必须将该文件放在src目录下,也就是说要跟你的包名在同一个目录下哟,或者说是在classpath路径下也可以! 37 InputStream in = Utils.class.getClassLoader().getResourceAsStream("config.properties"); 38 Properties pro = new Properties(); 39 pro.load(in); 40 DriverName=pro.getProperty("DriverName"); 41 url = pro.getProperty("url"); 42 username = pro.getProperty("username"); 43 password = pro.getProperty("password"); 44 } 45 46 47 public static Connection getConnection(){ 48 return con; 49 } 50 51 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note2; 8 9 import java.sql.Connection; 10 import java.sql.SQLException; 11 12 import org.apache.commons.dbutils.DbUtils; 13 import org.apache.commons.dbutils.QueryRunner; 14 15 /* 16 * 使用QueryRunner类,实现对数据表的 17 * insert delete update 18 * 调用QueryRunner类的方法 update (Connection con,String sql,Object...param) 19 * Object...param 可变参数,Object类型,SQL语句会出现?占位符 20 * 数据库连接对象,自定义的工具类传递 21 */ 22 public class QueryRunnerDemo { 23 private static Connection conn = Utils.getConnection(); 24 public static void main(String[] args)throws SQLException { 25 // insert(); 26 // update(); 27 delete(); 28 } 29 /* 30 * 定义方法,使用QueryRunner类的方法delete将数据表的数据删除 31 */ 32 public static void delete()throws SQLException{ 33 //创建QueryRunner类对象 34 QueryRunner qr = new QueryRunner(); 35 //写删除的SQL语句 36 String sql = "DELETE FROM classmate WHERE id<=?"; 37 //调用QueryRunner方法update 38 int row = qr.update(conn, sql, 10); 39 System.out.printf("已经有[%d]发生了改变",row); 40 /* 41 * 判断insert,update,delete执行是否成功 42 * 对返回值row判断 43 * if(row>0) 执行成功 44 */ 45 DbUtils.closeQuietly(conn); 46 } 47 48 /* 49 * 定义方法,使用QueryRunner类的方法update将数据表的数据修改 50 */ 51 public static void update()throws SQLException{ 52 //创建QueryRunner类对象 53 QueryRunner qr = new QueryRunner(); 54 //写修改数据的SQL语句 55 String sql = "UPDATE classmate SET age=? WHERE name=?"; 56 //定义Object数组,存储?中的参数,注意传入的位置哟,不要把顺序写反了! 57 Object[] params = {18,"尹正杰"}; 58 //调用QueryRunner方法update 59 int row = qr.update(conn, sql, params); 60 System.out.printf("已经有[%d]发生了改变",row); 61 DbUtils.closeQuietly(conn); 62 } 63 64 /* 65 * 定义方法,使用QueryRunner类的方法update向数据表中,添加数据 66 */ 67 public static void insert()throws SQLException{ 68 //创建QueryRunner类对象 69 QueryRunner qr = new QueryRunner(); 70 String sql = "INSERT INTO classmate VALUES(?,?,?,?,?,?,?,?,?,?)"; 71 //将三个?占位符的实际参数,写在数组中 72 Object[] params = {null,"方合意",24,"python开发工程师",100,60,89,94,92,87}; 73 //调用QueryRunner类的方法update执行SQL语句 74 System.out.println(conn); 75 int row = qr.update(conn, sql, params); 76 System.out.printf("已经有[%d]发生了改变",row); 77 DbUtils.closeQuietly(conn); 78 } 79 }
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集合 |
接下来我们一起对上面的八种方法进行一一举例,测试代码如下:

1 DriverName=com.mysql.jdbc.Driver 2 #zai "url" lu jing hou jia "?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true" ke yi kai qi pi chu li mo shi ! 3 url=jdbc:mysql://192.168.0.254:5200/yinzhengjie?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true 4 username=root 5 password=yinzhengjie

1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.note2; 7 8 import java.io.InputStream; 9 import java.sql.Connection; 10 import java.sql.DriverManager; 11 import java.util.Properties; 12 13 /* 14 * 编写数据库连接的工具类,JDBC工具类 15 * 获取连接对象采用读取配置文件方式 16 * 读取文件获取连接,执行一次,static{} 17 */ 18 public class Utils { 19 private static Connection con ; 20 private static String DriverName; 21 private static String url; 22 private static String username; 23 private static String password; 24 25 static{ 26 try{ 27 readConfig(); 28 Class.forName(DriverName); 29 con = DriverManager.getConnection(url, username, password); 30 }catch(Exception ex){ 31 throw new RuntimeException("数据库连接失败"); 32 } 33 } 34 35 private static void readConfig()throws Exception{ 36 //注意!想要使用"config.properties"这个配置文件,就必须将该文件放在src目录下,也就是说要跟你的包名在同一个目录下哟,或者说是在classpath路径下也可以! 37 InputStream in = Utils.class.getClassLoader().getResourceAsStream("config.properties"); 38 Properties pro = new Properties(); 39 pro.load(in); 40 DriverName=pro.getProperty("DriverName"); 41 url = pro.getProperty("url"); 42 username = pro.getProperty("username"); 43 password = pro.getProperty("password"); 44 } 45 46 47 public static Connection getConnection(){ 48 return con; 49 } 50 51 }

1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note2; 8 9 public class Student { 10 private int ID; 11 private String Name; 12 private int Age; 13 private String Job; 14 private int Chinese; 15 private int English; 16 private int Math; 17 private int Physics; 18 private int Chemistry; 19 private int Biology; 20 public Student(int iD, String name, int age, String job, int chinese, int english, int math, int physics,int chemistry, int biology) { 21 super(); 22 ID = iD; 23 Name = name; 24 Age = age; 25 Job = job; 26 Chinese = chinese; 27 English = english; 28 Math = math; 29 Physics = physics; 30 Chemistry = chemistry; 31 Biology = biology; 32 } 33 public Student() { 34 super(); 35 } 36 public int getID() { 37 return ID; 38 } 39 public void setID(int iD) { 40 ID = iD; 41 } 42 public String getName() { 43 return Name; 44 } 45 public void setName(String name) { 46 Name = name; 47 } 48 public int getAge() { 49 return Age; 50 } 51 public void setAge(int age) { 52 Age = age; 53 } 54 public String getJob() { 55 return Job; 56 } 57 public void setJob(String job) { 58 Job = job; 59 } 60 public int getChinese() { 61 return Chinese; 62 } 63 public void setChinese(int chinese) { 64 Chinese = chinese; 65 } 66 public int getEnglish() { 67 return English; 68 } 69 public void setEnglish(int english) { 70 English = english; 71 } 72 public int getMath() { 73 return Math; 74 } 75 public void setMath(int math) { 76 Math = math; 77 } 78 public int getPhysics() { 79 return Physics; 80 } 81 public void setPhysics(int physics) { 82 Physics = physics; 83 } 84 public int getChemistry() { 85 return Chemistry; 86 } 87 public void setChemistry(int chemistry) { 88 Chemistry = chemistry; 89 } 90 public int getBiology() { 91 return Biology; 92 } 93 public void setBiology(int biology) { 94 Biology = biology; 95 } 96 @Override 97 public String toString() { 98 99 return "ID="+ID+", 姓名="+Name+", 年龄="+Age+", 工作="+Job+", 语文="+Chinese+", 英语="+English+", 数学="+Math+", 物理="+Physics+", 化学="+Chemistry+", 生物="+Biology; 100 } 101 102 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 7 package cn.org.yinzhengjie.note2; 8 9 import java.sql.Connection; 10 import java.sql.SQLException; 11 import java.util.List; 12 import java.util.Map; 13 14 import org.apache.commons.dbutils.QueryRunner; 15 import org.apache.commons.dbutils.handlers.ArrayHandler; 16 import org.apache.commons.dbutils.handlers.ArrayListHandler; 17 import org.apache.commons.dbutils.handlers.BeanHandler; 18 import org.apache.commons.dbutils.handlers.BeanListHandler; 19 import org.apache.commons.dbutils.handlers.ColumnListHandler; 20 import org.apache.commons.dbutils.handlers.MapHandler; 21 import org.apache.commons.dbutils.handlers.MapListHandler; 22 import org.apache.commons.dbutils.handlers.ScalarHandler; 23 24 /* 25 * QueryRunner数据查询操作: 26 * 调用QueryRunner类方法query(Connection con,String sql,ResultSetHandler r, Object..params) 27 * ResultSetHandler r 结果集的处理方式,传递ResultSetHandler接口实现类 28 * Object..params SQL语句中的?占位符 29 * 30 * 注意: query方法返回值,返回的是T 泛型, 具体返回值类型,跟随结果集处理方式变化 31 */ 32 public class QueryRunnerDemo1 { 33 private static Connection con = Utils.getConnection(); 34 public static void main(String[] args) throws SQLException{ 35 // arrayHandler(); 36 // arrayListHandler(); 37 // beanHandler(); 38 // beanListHander(); 39 // columnListHandler(); 40 // scalarHandler(); 41 // mapHandler(); 42 mapListHandler(); 43 } 44 /* 45 * 结果集第一种处理方法, ArrayHandler,不推荐使用! 46 * 将结果集的第一行存储到对象数组中 Object[] 47 */ 48 public static void arrayHandler()throws SQLException{ 49 QueryRunner qr = new QueryRunner(); 50 String sql = "SELECT * FROM classmate"; 51 //调用方法query执行查询,传递连接对象,SQL语句,结果集处理方式的实现类 52 //返回对象数组 53 Object[] result = qr.query(con, sql, new ArrayHandler()); 54 for(Object obj : result){ 55 System.out.print(obj); 56 } 57 } 58 59 60 61 /* 62 * 结果集第二种处理方法,ArrayListHandler 63 * 将结果集的每一行,封装到对象数组中, 出现很多对象数组 64 * 对象数组存储到List集合 65 */ 66 public static void arrayListHandler()throws SQLException{ 67 QueryRunner qr = new QueryRunner(); 68 String sql = "SELECT * FROM classmate"; 69 //调用query方法,结果集处理的参数上,传递实现类ArrayListHandler 70 //方法返回值 每行是一个对象数组,存储到List 71 List<Object[]> result= qr.query(con, sql, new ArrayListHandler()); 72 73 //集合的遍历 74 for( Object[] objs : result){ 75 //遍历对象数组 76 for(Object obj : objs){ 77 System.out.print(obj+","); 78 } 79 System.out.println(); 80 } 81 } 82 83 84 /* 85 * 结果集第三种处理方法,BeanHandler 86 * 将结果集的第一行数据,封装成JavaBean对象 87 * 注意: 被封装成数据到JavaBean对象, Sort类必须有空参数构造 88 */ 89 public static void beanHandler()throws SQLException{ 90 QueryRunner qr = new QueryRunner(); 91 String sql = "SELECT * FROM classmate"; 92 //调用方法,传递结果集实现类BeanHandler 93 //BeanHandler(Class<T> type) 94 Student s = qr.query(con, sql, new BeanHandler<Student>(Student.class)); 95 System.out.println(s); 96 } 97 98 99 100 /* 101 * 结果集第四种处理方法, BeanListHandler 102 * 结果集每一行数据,封装JavaBean对象 103 * 多个JavaBean对象,存储到List集合 104 */ 105 public static void beanListHander()throws SQLException{ 106 QueryRunner qr = new QueryRunner(); 107 String sql = "SELECT * FROM classmate "; 108 //调用方法query,传递结果集处理实现类BeanListHandler 109 List<Student> list = qr.query(con, sql, new BeanListHandler<Student>(Student.class)); 110 for(Student s : list){ 111 System.out.println(s); 112 } 113 } 114 115 /* 116 * 结果集第五种处理方法,ColumnListHandler 117 * 结果集,指定列的数据,存储到List集合 118 * List<Object> 每个列数据类型不同 119 */ 120 public static void columnListHandler()throws SQLException{ 121 QueryRunner qr = new QueryRunner(); 122 String sql = "SELECT * FROM classmate "; 123 //调用方法 query,传递结果集实现类ColumnListHandler 124 //实现类构造方法中,使用字符串的列名 125 List<Object> list = qr.query(con, sql, new ColumnListHandler<Object>("name")); 126 for(Object obj : list){ 127 System.out.println(obj); 128 } 129 } 130 131 132 /* 133 * 结果集第六种处理方法,ScalarHandler 134 * 对于查询后,只有1个结果 135 */ 136 public static void scalarHandler()throws SQLException{ 137 QueryRunner qr = new QueryRunner(); 138 String sql = "SELECT COUNT(*) FROM classmate"; 139 //调用方法query,传递结果集处理实现类ScalarHandler 140 long count = qr.query(con, sql, new ScalarHandler<Long>()); 141 System.out.println(count); 142 } 143 144 /* 145 * 结果集第七种处理方法,MapHandler 146 * 将结果集第一行数据,封装到Map集合中 147 * Map<键,值> 键:列名 值:这列的数据 148 */ 149 public static void mapHandler()throws SQLException{ 150 QueryRunner qr = new QueryRunner(); 151 //注意,这里是可以用占位符哟,我下面就对他进行了传参,参数为11 152 String sql = "SELECT * FROM classmate where id = ?"; 153 //调用方法query,传递结果集实现类MapHandler 154 //返回值: Map集合,Map接口实现类, 泛型 155 Map<String,Object> map = qr.query(con, sql, new MapHandler(),11); 156 //遍历Map集合 157 for(String key : map.keySet()){ 158 System.out.println(key+".."+map.get(key)); 159 } 160 } 161 162 /* 163 * 结果集第八种处理方法,MapListHandler 164 * 将结果集每一行存储到Map集合,键:列名,值:数据 165 * Map集合过多,存储到List集合 166 */ 167 public static void mapListHandler()throws SQLException{ 168 QueryRunner qr = new QueryRunner(); 169 String sql = "SELECT * FROM classmate"; 170 //调用方法query,传递结果集实现类MapListHandler 171 //返回值List集合, 存储的是Map集合 172 List<Map<String,Object>> list = qr.query(con, sql, new MapListHandler()); 173 //遍历集合list 174 for( Map<String,Object> map : list ){ 175 for(String key : map.keySet()){ 176 System.out.print(key+"..."+map.get(key)+", "); 177 } 178 System.out.println(); 179 } 180 181 } 182 }