JDBC之DAO层封装思想超详解(下)

简介: JDBC之DAO层封装思想超详解(下)

2.6 测试结果演示

ps:

以下测试功能按部门表为例详细展示,员工表亦是相同做法,故不做员工表做详细演示

2.6.1 测试部门DAO实现类

①尝试添加数据到t_department中

更新数据前:

代码演示如下:

@Test
    //测试添加数据
    public void test01(){
        Scanner input=new Scanner(System.in);
        System.out.print("请输入部门名称:");
        //注:这里要么全用nextLine(),要么全不用
        String dname=input.nextLine();
        System.out.print("请输入部门简介:");
        String description=input.nextLine();
        department d=new department(dname,description);
        DepartmentDAOlmpl dao=new DepartmentDAOlmpl();
        boolean b = dao.addDepartment(d);
        System.out.println(b?"添加成功":"添加失败");
        input.close();
    }

②查询t_department所有的数据

@Test
    //查询t_employee表中所有的信息
    public void test04(){
        DepartmentDAOlmpl dao=new DepartmentDAOlmpl();
        List<department> allDepartment = dao.getAllDepartment();
        allDepartment.forEach(t -> System.out.println(t));
    }

③尝试更新数据,修改t_department表的用户指定的did字段那行的dname与description字段的值

更新之前:

更新数据代码演示如下:

@Test
    //测试方法test3的优化版
    //尝试修改t_department表的用户指定的did字段那行的dname与description字段的值
    public void test03_1(){
        DepartmentDAOlmpl dao=new DepartmentDAOlmpl();
        Scanner input=new Scanner(System.in);
        System.out.print("请输入要修改的部门编号:");
        int did=input.nextInt();
        input.nextLine();
        department department = dao.getBydid(did);
        System.out.print("请输入部门新名称("+department.getDname()+"):");
        //注:这里要么全用nextLine(),要么全不用
        String dname=input.nextLine();
        //如果什么都输入,就默认使用原来的部门名称
        if (dname.trim().length()==0){
            dname=department.getDname();
        }
        System.out.print("请输入部门新简介("+department.getDescription()+"):");
        String description=input.nextLine();
        if (description.trim().length()==0){
            description=department.getDescription();
        }
        input.close();
        department=new department(department.getDid(),dname,description);
        boolean b = dao.updateDepartment(department);
        System.out.println(b?"更新成功":"更新失败");
/*
      参数索引越界异常
      java.lang.RuntimeException: java.sql.SQLException: Parameter index out of range (3 > number of parameters, which is 2).
       可能原因:可能是update的sql语句的标点写了中文的标点符号
*/
    }

④尝试查询部门编号为4的数据

代码演示如下:

@Test
    //查询t_department表指定did的行的记录
    public void test05(){
        Scanner input=new Scanner(System.in);
        System.out.print("请输入部门编号:");
        int did=input.nextInt();
        DepartmentDAOlmpl dao=new DepartmentDAOlmpl();
        department department = dao.getBydid(did);
        System.out.println(department);
        input.close();
    }

⑤尝试删除部门编号为1012的数据

删除之前:

删除代码演示如下:

@Test
    //测试删除数据
    public void test02(){
        Scanner input=new Scanner(System.in);
        System.out.print("请输入部门编号:");
        //注:这里要么全用nextLine(),要么全不用
        int did=input.nextInt();
        department d=new department(did);
        DepartmentDAOlmpl dao=new DepartmentDAOlmpl();
        boolean b = dao.removeDepart(d);
        System.out.println(b?"删除成功":"删除失败");
        input.close();
    }


三、Dbutils优化代码

可引入Dbutils对DAO层的BaseDAOImpl类进行优化,其余代码不变,实现的功能亦是相同

3.1 Dbutils简介

dbutils,全称commons-dbutils,它 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。

其中QueryRunner类封装了SQL的执行,是线程安全的。

  1. 可以实现增、删、改、查、批处理。
  2. 考虑了事务处理需要共用Connection。
  3. 该类最主要的就是简单化了SQL查询,它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。
  4. 不需要手动关闭连接,runner会自动关闭连接,释放到连接池中

3.2 如何使用Dbutils?

使用前提:

使用之前先导入Dbutils的jar包,导入步骤可参考我的这篇博客Java SE: JUnit快速入门指南,导入的步骤和它一模一样,只是jar包的名字不一样而已

(1)更新

public int update(Connection conn, String sql, Object... params) throws SQLException用来执行一个更新(插入、更新或删除)操作。

(2)插入

public T insert(Connection conn,String sql,ResultSetHandler rsh, Object… params) throws SQLException:只支持INSERT语句,其中 rsh - The handler used to create the result object from the ResultSet of auto-generated keys. 返回值: An object generated by the handler.即自动生成的键值

(3)批处理

public int[] batch(Connection conn,String sql,Object[][] params)throws SQLException: INSERT, UPDATE, or DELETE语句

public T insertBatch(Connection conn,String sql,ResultSetHandler rsh,Object[][] params)throws SQLException:只支持INSERT语句

(4)使用QueryRunner类实现查询

public Object query(Connection conn, String sql, ResultSetHandler rsh,Object... params) throws SQLException执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法会自行处理 PreparedStatement 和 ResultSet 的创建和关闭。

ResultSetHandler接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。

ResultSetHandler 接口提供了一个单独的方法:Object handle (java.sql.ResultSet rs)该方法的返回值将作为QueryRunner类的query()方法的返回值。

该接口有如下实现类可以使用:

  • BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
  • BeanListHandler将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
  • ScalarHandler查询单个值对象
  • MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
  • MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
  • ColumnListHandler:将结果集中某一列的数据存放到List中。
  • KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
  • ArrayHandler:把结果集中的第一行数据转成对象数组。
  • ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。

3.3 BaseDAOImply优化版

代码演示如下:

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import util.JDBCToolsFinal;
import java.sql.SQLException;
import java.util.List;
public class BaseDAOImpl {
    private QueryRunner queryRunner=new QueryRunner();
    //通用的增,删,改的方法
    /**
     *
     * @param sql : 执行的sql语句
     * @param args :sql中有多少个?,就有多少个args,用来替代?并赋值
     * @return int : 影响的记录条数
     * @throws SQLException : 可能出现的sql异常
     */
    protected int update(String sql,Object ...args) throws SQLException{
        return queryRunner.update(JDBCToolsFinal.getConnection(),sql, args);
    }
    /**
     * 通用查询多个JavaBean对象的方法
     * @param clazz Class JavaBean.对象的类型的Class对象
     * @param sql  执行的sql语句
     * @param args Object ...为sqL中的?赋值,如果没有?,可以不传args实参
     * @param <T>  java.Been包中类的类型
     * @return List<T>  里面包含查询出来的多个的T对象
     * @throws Exception : 可能出现的sql异常
     */
    protected <T> List<T>  getList(Class clazz,String sql,Object ...args) throws Exception{
        return queryRunner.query(JDBCToolsFinal.getConnection(),sql,new BeanListHandler<T>(clazz),args);
    }
    /**
     * 通用查询单个JavaBean对象的方法
     * @param clazz Class JavaBean.对象的类型的Class对象
     * @param sql  执行的sql语句
     * @param args Object ...为sqL中的?赋值,如果没有?,可以不传args实参
     * @param <T>  java.Been包中类的类型
     * @return T  一个JavaBean对象
     * @throws Exception : 可能出现的sql异常
     */
    protected <T> T  getBean(Class clazz,String sql,Object ...args) throws Exception{
        return queryRunner.query(JDBCToolsFinal.getConnection(),sql,new BeanHandler<T>(clazz),args);
        /*
        BeanHandler.类的对象作用是把数据库中的表中的一条记录封装为一个JavaBean.对象,
        这条记录对应的是T类型的对象,如果创建T类型的对象,是通过clazz对象来完成,
        clazz是T类型的Class对象。
        */
    }
    //通用的查询某个值的方法
    protected Object getValue(String sql,Object ... args) throws SQLException {
        return queryRunner.query(JDBCToolsFinal.getConnection(),sql,new ScalarHandler(),args);
        //ScalarHandler对象的作用是把sgL查询结果中的单个值返回
    }
    //批处理:批量执行一组sql命令
    protected void batch(String sql,Object[][] args) throws SQLException {
        queryRunner.batch(JDBCToolsFinal.getConnection(),sql,args);
    }
}


相关文章
|
2月前
|
SQL Java 数据库连接
JDBC如何封装成Mybaits持久层框架只需4
本文主要讲解JDBC怎么演变到Mybatis的渐变过程,重点讲解了为什么要将JDBC封装成Mybaits这样一个持久层框架。再而论述Mybatis作为一个数据持久层框架本身有待改进之处。
17 0
|
2月前
|
SQL druid Java
JDBC技术【分页查询、数据库连接池、应用程序分层、封装通用的BaseDao】(四)-全面详解(学习总结---从入门到深化)
JDBC技术【分页查询、数据库连接池、应用程序分层、封装通用的BaseDao】(四)-全面详解(学习总结---从入门到深化)
30 0
|
3月前
|
SQL Java 数据库连接
JDBC技术【分页查询、数据库连接池、应用程序分层、封装通用的BaseDao】(四)-全面详解(学习总结---从入门到深化)(下)
JDBC技术【分页查询、数据库连接池、应用程序分层、封装通用的BaseDao】(四)-全面详解(学习总结---从入门到深化)
363 1
|
3月前
|
SQL Java 数据库连接
JDBC技术【分页查询、数据库连接池、应用程序分层、封装通用的BaseDao】(四)-全面详解(学习总结---从入门到深化)(中)
JDBC技术【分页查询、数据库连接池、应用程序分层、封装通用的BaseDao】(四)-全面详解(学习总结---从入门到深化)
28 0
|
3月前
|
SQL 存储 Java
JDBC技术【封装JDBC工具类、Statement的使用、PreparedStatement的使用(重点)、ResultSet的使用】(二)-全面详解(学习总结---从入门到深化)
JDBC技术【封装JDBC工具类、Statement的使用、PreparedStatement的使用(重点)、ResultSet的使用】(二)-全面详解(学习总结---从入门到深化)
37 0
|
8月前
|
Java 数据库连接
Java 中封装JDBC连接到JDBCUtils工具类的详解
Java 中封装JDBC连接到JDBCUtils工具类的详解
41 0
|
7月前
|
SQL Java 关系型数据库
[Mysql]JDBC篇, DAO, DBUtils, 批处理, 数据库池
面向接口编程是一种抽象的, 高效的编程思想 (就像Java里面的多态的思想. 解耦合) 解耦合 : 降低程序的耦合度(乐高坏了只需要换一个零件, 不香?), 提高程序的扩展力(比如多态) SUN公司写了一个接口 各大厂商对这个接口进行实现 这个接口实现了"多态"的编程思想 面向接口编程的程序员只需要调用JDBC即可 底层的实现是厂商写的代码, 程序员也不用去关心 厂商写的实现接口的.class文件, 也是驱动(Driver) 数据库驱动都是以.jar包的形式存在, .jar包当中有很多.class文件, 它们实现了JDBC接口
|
8月前
|
Java 关系型数据库 MySQL
JDBC之DAO层封装思想超详解(中3)
JDBC之DAO层封装思想超详解(中3)
|
8月前
|
SQL 数据可视化 Java
JDBC之DAO层封装思想超详解(上)
JDBC之DAO层封装思想超详解(上)
|
3月前
|
SQL Java 关系型数据库
MySQL之JDBC(二)
MySQL之JDBC(二)
34 0