scl 2017-10-11
新一次的内部提升开始了,如果您想写一个框架从Apache Commons DbUtils开始学习是一种不错的选择,我们先学习应用这个小“框架”再把源代码理解,然后写一个属于自己的ORM框架不是梦。
DbUtils是Apache下commons工具集中的一个小工具,它主要是对JDBC封装的ORM小工具,简化了JDBC的操作。之所以把它称之为工具而不是框架,是因为它和其他的ORM框架还是由很大的区别(例如Hibernate)。DbUtils并不支持所谓的聚合关联映射、缓存机制、实体状态的管理、延迟加载技术等等,它纯粹只是对JDBC的API进行封装。但也由于它的这种简单,因此性能高也是它的特点。DbUtils的源代码并不多,也很容易读得懂,非常适合于初学者阅读和学习。
对象关系映射(Object Relational Mapping),简称ORM。网上有很多专业的解释,但对于初学者来说这些专业的术语也许不太好理解。所以我们还是通过一些实际例子来说明。
在日常的开发中我们经常用到实体或者DTO对象,这似乎对每一个程序员来说都是再熟悉不过的了。但这些所谓的实体或者DTO对象按照领域驱动设计的说法,它们只有自己的属性,却没有属于自己的业务行为(get和set那不叫业务行为)。因此我们把他们称之为贫血模型。那用这些贫血模型来做什么呢?没错,就是封装数据。我们经常会将一些不同类型的数据封装到这些对象中。
给对象属性赋完值以后,便把这个实体传递给Dao层执行保存操作。最终将数据持久化到数据库的某张表中。
在这个过程我们发现一点,数据在Java中是以对象的形式存储,而最终持久化到数据库的时候是以关系型表格的形式存储,也就是说,我们把一个对象化结构的数据映射到了关系型数据库中的这个过程,就是对象关系映射。反之,当我们从关系型数据库中查询出的数据,又转换成一个对象模型的数据结构,这也是对象关系映射。
因此,我们可以将对象关系映射理解为它是一种对象模型和关系型数据库之间相互转换的过程。在实际开发中,我们会遇到大量的ORM操作,然而你会发现,这种操作其实大部分都是重复劳动,频繁的给PreparedStatment设置参数,又或者是频繁的从ResultSet中读取数据保存到实体中,这些操作让我们在开发中降低了效率。我们能否将这些繁琐的操作封装起来,我给你一个实体,你会自动帮我保存到数据库。我告诉你一个对象的类型,你会自动将结果集中的数据封装到这个对象中返回给我。这样就大大简化的JDBC的操作,提高了开发效率。接下来我们所学习的DbUtils就帮我们完成了这些事情。
安装:
教程中使用的是1.6的版本,下载的压缩包是 commons-dbutils-1.6-bin.zip。解压后将commons-dbutils-1.6.jar导入工程即可。
首先,我们在数据中创建USERS_INFO表。(mysql数据库)
这里我们使用DBCP连接池作为数据源。DBCP也是commons工具集中一个小工具。简单点说,它主要用于监听和管理JDBC的Connection对象,达到连接复用的效果(连接池的原理及好处可以在JDBC教程的章节中进行查阅)。
接下来编写一个DBCP连接池的工具类,用于获取DataSource
4.1、QueryRunner类
这个类用于发送执行SQL语句并返回相应的结果。其实现当中对Connection以及PreparedStatment接口的API进行了封装。QueryRunner有两种方式来管理连接,一种是在构建QueryRunner实例时通过构造方法传递一个数据源DataSource实例;另一种则是在调用相应的操作方法,如query、update、batch等这些方法时传入一个Connection对象。这两种方式有什么区别呢?通过源码的阅读,我们不难发现,其实对于DataSource的管理,在每次执行完相应操作后,DbUtils会自动关闭数据源的连接对象。而在调用相应的操作方法时传入的Connection对象,在使用完之后是需要我们手动去关闭这个资源的。在以下所有的例子中,我们都将使用DataSouce的方式进行操作。
4.2、Insert操作
4.3、Update操作
4.4、Delete操作
5.1、ResultSetHandler接口
这个接口的核心作用是将查询结果进行封装(O/R Mapping)。它有许多不同的实现类,每一个实现类都将ResultSet中的结果封装成不同类型的数据对象。如下图:
在ResultSetHandler众多的处理器实现类中主要分为两类,一类是处理单条结果集的,一类是处理多条结果集的。
单条数据处理器:BeanHandler、ArrayHandler、MapHandler、ScalarHandler
多条数据处理器:AbstractKeyedHandler(KeyedHandler、BeanMapHandler)、AbstractListHandler(ColumnListHandler、ArrayListHandler、MapListHandler)
5.2、BeanHandler
将单条查询结果封装为Bean对象
使用BeanHandler查询单条记录:
将多条查询结果封装为List集合,集合中的每个元素都是一个Bean对象
5.3、ArrayHandler
将单条查询结果封装为一个Object数组
5.4、ArrayListHandler
将多条查询结果封装为List集合,集合中的每个元素都是一个Object数组
5.5、MapHandler
将单条查询结果封装为一个Map对象, Key保存的是查询的列名,Value保存的是列的值
5.6、MapListHandler
将多条查询结果封装为一个List集合,集合中的每个元素都是一个Map对象
5.7、ScalarHandler
将单条查询结果中的某一列转换为指定的类型
5.8、ColumnListHandler
将多条查询结果中的某一列封装为List集合
5.9、KeyedHandler
将多条查询结果转换为Map,并将某列保存为Key,而Value则与MapHandler的查询结果一样,封装的是一个Map集合
5.10. BeanMapHandler
将多条查询结果转换为Map,并将某列保存为Key,而Value则与BeanHandler的查询结果一样,封装的是一个Bean对象
6.1、作业要求
1. 任意数据库,建立一个表student,字段有id,name(id是自增长的,name是char类型)
2. 利用DbUtils完成CRUD操作
3. insert操作要能得到返回的自增长值
4. Connection对象要能正确处理
6.2、提交内容
1. 整个项目的源代码打包发到我的qq或者直接把你的项目的git地址告诉我即可
6.3、提交时间
2017-11-2号 星期四 中午12:00前
7.1、参考
https://coding.net/u/david_cj/p/dbutils-demo/git 陈军老师写的详细教程
http://www.cnblogs.com/best/p/7474442.html Git的使用
https://commons.apache.org/proper/commons-dbutils/ 官网
7.2、资料下载