封装了JDBC,简化了其操作数据库的步骤

一、执行sql语句

QueryRunner类

  1. update(String sql, Object… params) ,执行insert update delete操作
  2. query(String sql, ResultSetHandler rsh, Object… params) ,执行 select操作
public void test(){
        Connection connection = null;
        try {
            connection = DruidUtils.getConnection();
            QueryRunner queryRunner = new QueryRunner();
            String sql = "select * from t_user where `id` = ?";
            BeanHandler<User> beanHandler = new BeanHandler<>(User.class);
            //User种得有setter方法,且属性名应该和表数据中的字段名相同
            User user = queryRunner.query(connection, sql, beanHandler, 4);
            System.out.println(user);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DruidUtils.close(connection);
        }
    }

二、处理结果集

ResultSetHandler

2

public void test(){
        Connection connection = null;
        try {
            connection = DruidUtils.getConnection();
            QueryRunner queryRunner = new QueryRunner();
            String sql = "select * from t_user";
            BeanListHandler<User> beanListHandler = new BeanListHandler<>(User.class);
            List<User> userList = queryRunner.query(connection, sql, beanListHandler);
            userList.forEach(System.out::println);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DruidUtils.close(connection);
        }
    }

ScalarHandler用于查询表中的特殊值

比如count(*)/max()

返回object对象,需要强制转换成所需要的对象,如下

ScalarHandler handler = new ScalarHandler()
Date birth = (Date) runner.query(connection,sql,handle);

如果count需要转为long而不是int

三、注意事项

如果表中的字段名与类中的不一样,为了查询操作结果的准确性,我们需要编写sql时使用类的属性名作为select后字段的别名

原因(sql语句是如何执行的)

BeanHandler<Person> handler = new BeanHandler<>(Person.class);
//保存数据的Object对象的显式转换类型是由handler参数决定的
QueryRunner runner = new QueryRunner();
Person p = runner.query(connection,sql,handler,param);
//通过反射创建Person类的对象,后调用指定类的指定方法setXxx(),对相关属性xxx进行赋值

执行语句Person p = runner.query(connection,sql,handler,param);

通过参数handler的泛型确定需要查询和返回的类对象,并传入对应类的字节码文件

随后通过反射创建这个类的对象(调用Class类的newInstance()),即

Class personClass = Person.class;
Person person = personClass.newInsatance();

随后执行sql语句,通过反射执行setXxx方法(先调用personClass.getMethod()获取该方法,参数分别传入“set+sql语句查询到的结果的字段名(首字母大写)”,以及setXxx方法所需要的参数的类型对应的class对象,随后通过上述方法返回的method对象的invoke方法,参数传入sql查询到的对应的值))

Method method = personClass.getMethod(“setHeight”,int.class);//height为字段名,int为setHeight函数需要的参数类型

method.invoke(170);

这时我们会发现,如果调用传入的sql语句的字段名与类的属性名不同

如属性名为height,但字段名为person_height,则构造出的传给getMethod第一个参数的字符串为“setPerson_height”

则sql语句所构造出的setXxx语句在该类中找不到对应的方法(因为类中setXxx方法的Xxx对应类的属性名——setHeight())

所以无法成功执行赋值,故返回对象的各个值将为空

Q.E.D.


   七岁几胆敢预言自己,操一艘战机