DBUtils学习之——使用ResultSetHandler接口的各个实现类实现数据库的增删改查
本例展示的是使用ResultSetHandler接口的几个常见实现类实现数据库的增删改查,可以大大减少代码量,优化程序。
ResultSetHandler的各个实现类:
- ArrayHandler:把结果集中的第一行数据转成对象数组。
- ArrayListHandler:把结果集中的每一行数据都转成一个对象数组,再存放到List中。
- BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。//重点
- BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。//重点
- MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。//重点
- MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List //重点
- ColumnListHandler:将结果集中某一列的数据存放到List中。
- KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里(List<Map>),再把这些map再存到一个map里,其key为指定的列。
- ScalarHandler:将结果集第一行的某一列放到某个对象中。//重点
(一)首先,建立一个与数据库emp表相对应的一个实体类Emp,Emp类代码如下:
import java.util.Date; public class Emp { private Integer empno; private String ename; private String job; private Integer mgr; private Date hiredate; private Double sal; private Double comm; private Integer deptno; public Emp() { super(); } public Emp(Integer empno, String ename, String job, Integer mgr, Date hiredate, Double sal, Double comm, Integer deptno) { super(); this.empno = empno; this.ename = ename; this.job = job; this.mgr = mgr; this.hiredate = hiredate; this.sal = sal; this.comm = comm; this.deptno = deptno; } public Integer getEmpno() { return empno; } public void setEmpno(Integer empno) { this.empno = empno; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public Integer getMgr() { return mgr; } public void setMgr(Integer mgr) { this.mgr = mgr; } public Date getHiredate() { return hiredate; } public void setHiredate(Date hiredate) { this.hiredate = hiredate; } public Double getSal() { return sal; } public void setSal(Double sal) { this.sal = sal; } public Double getComm() { return comm; } public void setComm(Double comm) { this.comm = comm; } public Integer getDeptno() { return deptno; } public void setDeptno(Integer deptno) { this.deptno = deptno; } @Override public String toString() { return "Emp [empno=" + empno + ", ename=" + ename + ", job=" + job + ", mgr=" + mgr + ", hiredate=" + hiredate + ", sal=" + sal + ", comm=" + comm + ", deptno=" + deptno + "]"; } }
(二)为方便连接数据库,创建一个工具类JdbcUtils,类中代码如下:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import org.apache.commons.dbutils.DbUtils; public class JdbcUtils { //用于连接数据库的静态常量 private static String URL = "jdbc:oracle:thin:@localhost:1521:ORCL"; private static String USER = "scott"; private static String PASSWORD = "tiger"; //使用静态块加载驱动 static { DbUtils.loadDriver("oracle.jdbc.driver.OracleDriver"); } /** * 获得连接的静态方法 * @return */ public static Connection getConnection() { try { return (Connection) DriverManager.getConnection(URL, USER, PASSWORD); } catch (SQLException e) { System.out.println("获得数据连接失败:" + e.getMessage()); } return null; } /** * 编写程序过程中可使用main测试是否可以获得连接对象 */ public static void main(String[] args) { System.out.println(getConnection()); } }
(三)接下来创建一个JUnit测试类EmpCRUDTest,是对ResultSetHandler接口的几个常见实现类实现数据库的增删改查操作测试,代码如下:
import static org.junit.Assert.*; import java.math.BigDecimal; import java.sql.Connection; import java.sql.SQLException; import java.util.Date; import java.util.List; import java.util.Map; import org.apache.commons.dbutils.DbUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.ResultSetHandler; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.MapHandler; import org.apache.commons.dbutils.handlers.MapListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import org.junit.Test; public class EmpCRUDTest { // 所有CRUD的操作都通过此类完成 QueryRunner runner = new QueryRunner(); /** * BeanListHandler类测试 * BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。 */ @Test public void testSelect() { //调用工具类JdbcUtils的getConnection()方法获得连接 Connection conn = JdbcUtils.getConnection(); String sql = "select * from emp"; //创建BeanListHandler类实例 /*ResultSetHandler<List<Emp>> rsh = new BeanListHandler<Emp>(Emp.class);*/ ResultSetHandler<List<Emp>> rsh = new BeanListHandler<Emp>(Emp.class); try { //执行查询操作 List<Emp> list = runner.query(conn, sql, rsh); //遍历list查看返回结果 for (Emp e : list) { System.out.println(e); } } catch (SQLException e) { e.printStackTrace(); } finally { //关闭流 DbUtils.closeQuietly(conn); } } /** * BeanListHandler类有参数的情况测试 查询多个员工信息 * */ @Test public void testSelect2() { Connection conn = JdbcUtils.getConnection(); String sql = "select * from emp where sal between ? and ? and ename like ?"; ResultSetHandler<List<Emp>> rsh = new BeanListHandler<Emp>(Emp.class); try { // 为每个问号赋一个值绑定变量 List<Emp> list = runner.query(conn, sql, rsh, 1.0, 8888.0, "%A%"); for (Emp e : list) { System.out.println(e); } } catch (SQLException e) { e.printStackTrace(); } finally { DbUtils.closeQuietly(conn); } } /** * BeanHandler类测试 * BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。适用于查询结果只有一行的情况 */ @Test public void testSelect3() { Connection conn = JdbcUtils.getConnection(); //创建BeanHandler实例 BeanHandler<Emp> rsh = new BeanHandler<Emp>(Emp.class); String sql = "select * from emp where empno=?";//查询语句只会一行结果 try { //执行查询 Emp e = runner.query(conn, sql, rsh, 7698); //打印输出查看结果 System.out.println(e); } catch (SQLException e) { e.printStackTrace(); } finally { //关闭连接 DbUtils.closeQuietly(conn); } } /** * MapHandler操作结果集测试 查询成java.util.Map, Map<列名,值> 把结果集转为一个 Map 对象, 并返回. * 若结果集中有多条记录, 仅返回第一条记录对应的 Map 对象. Map 的键: 列名(而非列的别名), 值: 列的值 */ @Test public void testSelectForMap() { Connection conn = JdbcUtils.getConnection(); //创建MapHandler类实例 MapHandler mapHandler = new MapHandler(); //该查询语句会返回一条记录 String sql = "select * from emp where empno=?"; try { //执行SQl语句,记录的列名将作为map集合的key,列名对应的值则是map集合的value Map<String, Object> value = runner.query(conn, sql, mapHandler, 8888); //根据map的key获取对应的value,打印查看结果 System.out.println(value.get("EMPNO") + "," + value.get("ENAME") + "," + value.get("JOB") + "," + value.get("MGR") + "," + value.get("HIREDATE") + "," + value.get("SAL")); } catch (SQLException e) { e.printStackTrace(); } finally { DbUtils.closeQuietly(conn); } } /** * MapListHandler操作结果集测试 MapListHandler 类 (实现ResultSetHandler 接口)把从数据库中查询出的记录都 * 放到List集合当中, List集合中每一个对象都是Map类型,可以根据这条记录的字段名读出相对应的值. */ @Test public void testSelectForMapList() { Connection conn = JdbcUtils.getConnection(); //创建MapListHandler类实例 MapListHandler mapListHandler = new MapListHandler(); String sql = "select * from emp"; try { //执行SQL语句,会返回多条记录,每一条记录都保存在一个map集合中,而所有的集合都放在一个list中 List<Map<String, Object>> query = runner.query(conn, sql, mapListHandler); //遍历输出,查看结果 for (Map<String, Object> value : query) { System.out.println(value.get("EMPNO") + "," + value.get("ENAME") + "," + value.get("JOB") + "," + value.get("MGR") + "," + value.get("HIREDATE") + "," + value.get("SAL")); } } catch (SQLException e) { e.printStackTrace(); } finally { DbUtils.closeQuietly(conn); } } /** * 标量查询 * ScalarHandler:可以返回指定列的一个值或返回一个统计函数的值 */ @Test public void testSelectForScalar() { Connection conn = JdbcUtils.getConnection(); //SQl语句,为计数列起一个别名count String sql = "select count(*) count from emp"; //创建ScalarHandler类实例,传入的参数的列名, 返回大数据类型的结果 ScalarHandler<BigDecimal> scalarHandler = new ScalarHandler<BigDecimal>("count"); try { //执行SQl语句, 返回值是大数据类型的值 BigDecimal rows = runner.query(conn, sql, scalarHandler); System.out.println("共查询到了:"+rows.intValue()+"条记录");// 将rows转成int型 } catch (SQLException e) { e.printStackTrace(); } finally { DbUtils.closeQuietly(conn); } } /** * 插入数据测试 */ @Test public void testInsert() { Connection conn = JdbcUtils.getConnection(); java.sql.Date date = new java.sql.Date(new Date().getTime());// date作为时间插入数据库表中 String sql = "insert into emp(empno,ename,job,hiredate,sal,deptno) " + "values(?,?,?,?,?,?)"; try { //执行插入语句 int rows = runner.update(conn, sql, 8888, "JASSICA", "SALESMAN", date, 3344.0, 10); System.out.println("插入了:" + rows + "行"); } catch (SQLException e) { e.printStackTrace(); } finally { DbUtils.closeQuietly(conn); } } /** * 更新数据测试 */ @Test public void testUpdate() { Connection conn = JdbcUtils.getConnection(); String sql = "update emp set sal=?,deptno=? where empno=?"; try { int rows = runner.update(conn, sql, 4455, 20, 8888); System.out.println("更新了:" + rows + "行"); } catch (SQLException e) { e.printStackTrace(); } finally { DbUtils.closeQuietly(conn); } } }
刚刚学习,如见解有误欢迎指正!