如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils。
DBUtils就是JDBC的简化开发工具包。需要项目导入commons-dbutils-1.6.jar才能够正常使用DBUtils工具。
1.概述
DBUtils是java编程中的数据库操作实用工具,小巧简单实用。
DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码。
Dbutils三个核心功能介绍
- QueryRunner中提供对sql语句操作的API.
- ResultSetHandler接口,用于定义select操作后,怎样封装结果集.
- DbUtils类,它就是一个工具类,定义了关闭资源与事务处理的方法
2.事务的基本概念
事务是指一组最小逻辑操作单元,里面有多个操作组成。 组成事务的每一部分必须要同时提交成功,如果有一个操作失败,整个操作就回滚。
事务ACID特性
- 原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
- 一致性(Consistency) 事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
- 隔离性(Isolation) 事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
- 持久性(Durability) 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
3.QueryRunner核心类
- update(Connection conn, String sql, Object... params) ,用来完成表数据的增加、删除、更新操作
- query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) ,用来完成表数据的查询操作
package cn.jxufe.java.chapter12.demo01; import java.sql.Connection; import java.sql.SQLException; import org.apache.commons.dbutils.DbUtils; import org.apache.commons.dbutils.QueryRunner; import cn.jxufe.java.chapter11.jdbc_util.JDBCUtils; /* * 使用QueryRunner类,实现对数据表的 * insert delete update * 调用QueryRunner类的方法 update (Connection con,String sql,Object...param) * Object...param 可变参数,Object类型,SQL语句会出现?占位符 * 数据库连接对象,自定义的工具类传递 */ public class Test01QueryRunner { private static Connection con = JDBCUtils.getConnection(); public static void main(String[] args) throws SQLException { // TODO Auto-generated method stub // insert(); // update(); delete(); } /* * 定义方法,使用QueryRunner类的方法update向数据表中,添加数据 */ public static void insert() throws SQLException { // 创建QueryRunner类对象 QueryRunner qr = new QueryRunner(); String sql = "INSERT INTO sort(sname,sprice,sdesc) VALUES(?,?,?)"; // 将三个?占位符的实际参数,写在数组中 Object[] params = { "体育用品", 289.32, "购买体育用品" }; // 调用QueryRunner类的方法update执行SQL语句 int row = qr.update(con, sql, params); System.out.println(row); DbUtils.closeQuietly(con); } /* * 定义方法,使用QueryRunner类的方法update将数据表的数据修改 */ public static void update() throws SQLException { // 创建QueryRunner类对象 QueryRunner qr = new QueryRunner(); // 写修改数据的SQL语句 String sql = "UPDATE sort SET sname=?,sprice=?,sdesc=? WHERE sid=?"; // 定义Object数组,存储?中的参数 Object[] params = { "花卉", 100.88, "情人节玫瑰花", 4 }; // 调用QueryRunner方法update int row = qr.update(con, sql, params); System.out.println(row); DbUtils.closeQuietly(con); } /* * 定义方法,使用QueryRunner类的方法delete将数据表的数据删除 */ public static void delete() throws SQLException { // 创建QueryRunner类对象 QueryRunner qr = new QueryRunner(); // 写删除的SQL语句 String sql = "DELETE FROM sort WHERE sid=?"; // 调用QueryRunner方法update int row = qr.update(con, sql, 8); System.out.println(row); /* * 判断insert,update,delete执行是否成功 * 对返回值row判断 * if(row>0) 执行成功 */ DbUtils.closeQuietly(con); } }
4.QueryRunner实现查询操作
query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) ,用来完成表数据的查询操作
4.1ResultSetHandler结果集处理类
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集合 |
4.2JavaBean
JavaBean就是一个类,在开发中常用封装数据。具有如下特性
- 需要实现接口:java.io.Serializable ,通常实现接口这步骤省略了,不会影响程序。
- 提供私有字段:private 类型 字段名;
- 提供getter/setter方法:
- 提供无参构造
/* * 账务类 */ public class ZhangWu { private int id; private String name; private double money; private String parent; public ZhangWu() { super(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } public String getParent() { return parent; } public void setParent(String parent) { this.parent = parent; } @Override public String toString() { //该方法可以省略 return "ZhangWu [id=" + id + ", name=" + name + ", money=" + money + ", parent=" + parent + "]"; } }
4.3ArrayHandler与ArrayListHandler查询
- ArrayHandler:将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值
- ArrayListHandler:将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。
/* * 结果集第一种处理方法, ArrayHandler * 将结果集的第一行存储到对象数组中 Object[] */ public static void arrayHandler() throws SQLException { QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort"; Object[] result = qr.query(con, sql, new ArrayHandler()); for (Object object : result) { System.out.print(object + " "); } }
/* * 结果集第二种处理方法,ArrayListHandler * 将结果集的每一行,封装到对象数组中, 出现很多对象数组 * 对象数组存储到List集合 */ public static void arrayListHandler() throws SQLException { QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort"; List<Object[]> result = qr.query(con, sql, new ArrayListHandler()); // 集合的遍历 for (Object[] objs : result) { // 遍历对象数组 for (Object obj : objs) { System.out.print(obj + " "); } System.out.println(); } }
4.4BeanHandler与BeanListHandler查询
- BeanHandler :将结果集中第一条记录封装到一个指定的javaBean中。
- BeanListHandler :将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中。
// 注意:这个类要是一个public的主类 package cn.jxufe.java.chapter12.demo01; public class Sort { private int sid; private String sname; private double sprice; private String sdesc; public Sort() { // TODO Auto-generated constructor stub } public Sort(int sid, String sname, double sprice, String sdesc) { this.sid = sid; this.sname = sname; this.sprice = sprice; this.sdesc = sdesc; } public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public double getSprice() { return sprice; } public void setSprice(double sprice) { this.sprice = sprice; } public String getSdesc() { return sdesc; } public void setSdesc(String sdesc) { this.sdesc = sdesc; } @Override public String toString() { return "Sort [sid=" + sid + ", sname=" + sname + ", sprice=" + sprice + ", sdesc=" + sdesc + "]"; } }
/* * 结果集第三种处理方法,BeanHandler * 将结果集的第一行数据,封装成JavaBean对象 * 注意: 被封装成数据到JavaBean对象, Sort类必须有空参数构造 */ public static void beanHandler() throws SQLException { QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort "; // 调用方法,传递结果集实现类BeanHandler // BeanHandler(Class<T> type) Sort sort = qr.query(con, sql, new BeanHandler<>(Sort.class)); System.out.println(sort); }
/* * 结果集第四种处理方法, BeanListHandler * 结果集每一行数据,封装JavaBean对象 * 多个JavaBean对象,存储到List集合 */ public static void beanListHander() throws SQLException { QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort "; // 调用方法query,传递结果集处理实现类BeanListHandler List<Sort> list = qr.query(con, sql, new BeanListHandler<Sort>(Sort.class)); for (Sort s : list) { System.out.println(s); } }
4.5ColumnListHandler与ScalarHandler查询
- ColumnListHandler:将结果集中指定的列的字段值,封装到一个List集合中。
- ScalarHandler:它是用于单数据。例如select count(*) from 表操作。
/* * 结果集第五种处理方法,ColumnListHandler * 结果集,指定列的数据,存储到List集合 * List<Object> 每个列数据类型不同 */ public static void columnListHandler() throws SQLException { QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort "; // 调用方法 query,传递结果集实现类ColumnListHandler // 实现类构造方法中,使用字符串的列名 List<Object> list = qr.query(con, sql, new ColumnListHandler<Object>("sname")); 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 sort"; // 调用方法query,传递结果集处理实现类ScalarHandler long count = qr.query(con, sql, new ScalarHandler<Long>()); System.out.println(count); }
4.6MapHandler与MapListHandler查询
/* * 结果集第七种处理方法,MapHandler * 将结果集第一行数据,封装到Map集合中 * Map<键,值> 键:列名 值:这列的数据 */ public static void mapHandler() throws SQLException { QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort"; // 调用方法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 sort"; // 调用方法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(); } }
完整代码
package cn.jxufe.java.chapter12.demo01; 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; import cn.jxufe.java.chapter11.jdbc_util.JDBCUtils; /* * QueryRunner数据查询操作: * 调用QueryRunner类方法query(Connection con,String sql,ResultSetHandler r, Object..params) * ResultSetHandler r 结果集的处理方式,传递ResultSetHandler接口实现类 * Object..params SQL语句中的?占位符 * * 注意: query方法返回值,返回的是T 泛型, 具体返回值类型,跟随结果集处理方式变化 */ public class Test02QueryRunner { private static Connection con = JDBCUtils.getConnection(); public static void main(String[] args) throws SQLException { // TODO Auto-generated method stub // arrayHandler(); // arrayListHandler(); // beanHandler(); // beanListHander(); // columnListHandler(); // scalarHandler(); // mapHandler(); mapListHandler(); } /* * 结果集第一种处理方法, ArrayHandler * 将结果集的第一行存储到对象数组中 Object[] */ public static void arrayHandler() throws SQLException { QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort"; Object[] result = qr.query(con, sql, new ArrayHandler()); for (Object object : result) { System.out.print(object + " "); } } /* * 结果集第二种处理方法,ArrayListHandler * 将结果集的每一行,封装到对象数组中, 出现很多对象数组 * 对象数组存储到List集合 */ public static void arrayListHandler() throws SQLException { QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort"; 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 sort "; // 调用方法,传递结果集实现类BeanHandler // BeanHandler(Class<T> type) Sort sort = qr.query(con, sql, new BeanHandler<>(Sort.class)); System.out.println(sort); } /* * 结果集第四种处理方法, BeanListHandler * 结果集每一行数据,封装JavaBean对象 * 多个JavaBean对象,存储到List集合 */ public static void beanListHander() throws SQLException { QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort "; // 调用方法query,传递结果集处理实现类BeanListHandler List<Sort> list = qr.query(con, sql, new BeanListHandler<Sort>(Sort.class)); for (Sort s : list) { System.out.println(s); } } /* * 结果集第五种处理方法,ColumnListHandler * 结果集,指定列的数据,存储到List集合 * List<Object> 每个列数据类型不同 */ public static void columnListHandler() throws SQLException { QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort "; // 调用方法 query,传递结果集实现类ColumnListHandler // 实现类构造方法中,使用字符串的列名 List<Object> list = qr.query(con, sql, new ColumnListHandler<Object>("sname")); 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 sort"; // 调用方法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(); String sql = "SELECT * FROM sort"; // 调用方法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 sort"; // 调用方法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(); } } }