Java-DBUtils操作数据库
封装了JDBC,简化了其操作数据库的步骤
一、执行sql语句
QueryRunner类
- update(String sql, Object… params) ,执行insert update delete操作
- 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
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())
所以无法成功执行赋值,故返回对象的各个值将为空