DbUtils的基本用法

1. 简介

​ 使用 JDBC 时冗余的代码太多了,为了简化开发我们可以选择使用 DbUtils 。

​ Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。

2. 导入Jar包

下载网址:https://mirrors.tuna.tsinghua.edu.cn/apache//commons/dbutils/binaries/commons-dbutils-1.7-bin.zip

下载后解压,复制 commons-dbutils-1.7.jar 文件,导入项目即可。

image-20201219153048176

3. 核心类

3.1 DbUtils类

常用方法:

DbUtils.closeQuietly();  // 它有多种重载可以用于关闭 Connection Statement ResultSet等

3.2 QueryRunner类

构造方法:

QueryRunner();					// 无参构造,需要在使用时提供Connection对象,和自己手动关闭
QueryRunner(DataSource ds);		// 构造方法中给出数据源,查询时不必提供Connection对象,自然也没有关闭操作

一般使用有参构造,在DAO类中声明为成员变量,然后各个方法共用。这样在执行SQL语句时只有一行代码,看起来就很简洁了。

常用方法:

int update([Connection conn, ]String sql,Object... params); // 增 删 改 操作
T query([Connection conn, ]String sql,ResultSetHandler<T> handler,Object... params);
// 查询操作

update()方法很简单,就是传入SQL执行就行了,SQL中有 ?时,SQL之后跟着写上就行,返回值为受影响的行数。

如:

qr.update("update employee set salary=? where id=?",9000,4);  // 把id为4的员工的薪资改为9000

query()方法就是多了个 ResultSerHandler “结果集处理器” ,这是一个接口,作用就是处理结果集,它有多个实现类,也就是多种处理方式,如BeanHandler就是将结果集中的第一行打包成对应的实体类。在使用时只需要根据功能创建并传入所需对象即可。

各实现类的功能如下:

实现类说明
new ArrayHandler()将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值
new ArrayListHandler()将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。
new BeanHandler<Employee>(Employee.class)将结果集中第一条记录封装到一个指定的javaBean中(这里Employee就是一个实体类)
new BeanListHandler<Employee>(Employee.class)将结果集中指定的列的字段值,封装到一个List集合中
new ScalarHandler<Long>(1)获取结果集第一行,某一列的值。参数可为列名或列号,默认获取第一列数据。
常用来获取 Count( * ) 的结果,但注意它是 long 类型的
new ColumnListHandler(“name”)将结果集中指定的列的字段值,封装到一个List集合中,如本例就是获取name列,也可以传入列号,如果没有参数,默认获取第一列。
new MapHandler()将结果集中第一条记录封装到了Map集合中,key就是字段名称, value就是字段值
new MapListHandler()将结果集中每一条记录封装到了Map集合中,key就是字段名称, value就是字段值,在将这些Map封装到List集合中。
query 的返回值类型为 List<Map<String,Object>>
new KeyedHandler<Integer>(1)将结果集中每一条记录封装到Map,在将这个map集合做为另一个 Map的value,另一个Map集合的key是指定的字段的值。
本例 query 返回值类型为: Map<Integer,Map<String,Object>>
以第一列(id–int类型)为外层Map的key,这样就可以快捷的通过 id 找到每一行数据。

示例:

@Test // BeanHandler
public void test52() throws Exception{
    QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
    Employee e = qr.query("select * from employee where id=?", new BeanHandler<Employee>(Employee.class), 3);
    System.out.println(e);
}

@Test // ArrayListHandler
public void test70() throws Exception{
    QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
    List<Object[]> l = qr.query("select * from employee", new ArrayListHandler());
    for(Object[] o : l){
        System.out.println(Arrays.toString(o));
    }
}

关于泛型的一些解释:

​ 可以发现ResultSetHandler接口就是带泛型的,也就是说结果集处理器是支持泛型的,那这有什么用呢?通过查看 query 函数的定义image-20201219171026264可知:query是一个泛型方法,其返回值类型,由参数类型(也就是ResultSetHandler中出入的泛型参数 T)来决定。故:给 ResultSetHandler 指定泛型的作用就是确定返回值类型。

那为什么有些实现类不支持泛型呢?当然就是因为在继承 ResultSetHandler 时就确定了泛型。

如:ArrayHandler 其定义如下:

image-20201219171709958

可以发现 T 被指定为了 Object[] 类型。

还有,

既然传入泛型决定了query的返回值类型,那么BeanHandler为什么还要传入 类型对象 的参数呢?

可知,一定是通过反射机制,为我们分装返回的结果的,要进行反射操作,就要首先获得类的类对象,然而泛型只是在编译期有效,JVM无法通过泛型获取对应的类对象,因为在JVM的世界里就不存在泛型这个东西。所以我们需要手动传入。

4. 实体类

Java中以类对应数据库中的表,每一张表对应一个类,每一列对应类中的一个属性;每一行数据对应一个对象。

这样的类就是实体类,它们需要满足如下条件:

  1. 符合 Java Bean 规范

    1. 需要实现 序列化接口, Serializable (暂时可以省略)
    2. 提供私有字段: private 类型 变量名;
    3. 提供 getter 和 setter
    4. 提供 空参构造
  2. 类中的成员变量名需要与表中的字段名保持一致

    在开发中数据库名很重要,修改不易,所以是 成员变量名 以 表字段 名为准。

    那表字段名又如何设计呢?

    阿里云规范中:

    【强制】表名、字段名必须使用小写字母或数字 , 禁止出现数字开头,禁止两个下划线中间只出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。

    说明: MySQL 在 Windows 下不区分大小写,但在 Linux 下默认是区分大小写。因此,数据库名、 表名、字段名,都不允许出现任何大写字母,避免节外生枝。

    正例: aliyun _ admin , rdc _ config , level 3_ name 反例: AliyunAdmin , rdcConfig , level 3 name

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值