单表的 CURD 操作(第三讲)
Mapper 动态代理
在前面例子中自定义 Dao 接口实现类时发现一个问题: Dao 的实现类其实并没有干什么实质性的工作,它仅仅就是通过 SqISession 的相关 API 定位到映射文件 mapper 中相应 id 的 SQL 语句,真正对 DB 进行操作的工作其实是由框架通过 mappe r中的 SQL 完成的。
所以,MyBatis 框架就抛开了 Dao 的实现类,直接定位到映射文件 mapper 中的相应 SQL语句,对 DB 进行操作。这种对 Dao 的实现方式称为 Mapper 的动态代理方式。
Mapper 动态代理方式无需程序员实现 Dao 接口。接口是由 MyBatis 结合映射文件自动生成的动态代理实现的。
项目:MyBatis_Dynamic_Mapper,在前面项目的基础上进行如下修改操作。
映射文件的 namespace 属性值
一般情况下,一个 Dao 接口的实现类方法使用的是同一个 SQL 映射文件中的 SQL 映射 id。所以,MyBatis框架要求,将映射文件中<mapper/>标签的 namespace 属性设为 Dao 接口的全类名,则系统会根据方法所属 Dao 接口,自动到相应 namespace 的映射文件中查找相关的SQL映射。
简单来说,通过接口名即可定位到映射文件 mapper。
修改日志输出控制文件
mapper 的 namespace 修改了,则需要将日志输出控制文件中 logger 的输出对象进行修改。
Dao 接口方法名
MyBatis 框架要求,接口中的方法名,与映射文件中相应的 SQL 标签的 id 值相同。系统会自动根据方法名到相应的映射文件中查找同名的 SQL 映射 id。
简单来说,通过方法名就可定位到映射文件 mapper 中相应的 SQL 语句。
Dao 对象的获取
使用时,只需调用 SqlSession 的 getMapper() 方法,即可获取指定接口的实现类对象。该方法的参数为指定 Dao 接口类的class值。
删除 Dao 实现类
由于通过调用 Dao 接口的方法,不仅可以从 SQL 映射文件中找到所要执行 SQL 语句,还可通过方法参数及返回值,将 SQL 语句的动态参数传入,将查询结果返回。所以,Dao 的实现工作,完全可以由 MyBatis 系统自动根据映射文件完成。所以,
Dao 的实现类就不再需要了。
Dao 实现对象是由 JDK 的 Proxy 动态代理自动生成的。
修改测试类
(1)@Before 与 @After 注解方法
在 @Before 注解方法中获取到 SqISession 对象后,通过 SqlSession 的 getMapper() 方法创建 Dao 接口实现类的动态代理对象。
在 @After 注解方法中关闭 SqlSession 对象。
(2)添加 SqlSession 的提交方法
在增删改测试方法的最后,添加上 SqlSession 的 commit()方法,完成提交。
(3)删除 selectStudentMap() 方法测试
MyBatis 框架对于 Dao 查询的自动实现,底层只会调用 selectOne() 与 selectList() 方法。而框架选择方法的标准是测试类中用于接收返回值的对象类型。若接收类型为 List,则自动选择 selectList() 方法;否则,自动选择 selectOne() 方法。
这里接收类型为 Map,所以框架选择了 selectOne() 方法,会报错。所以这里需要删除这个 selectStudentMap() 方法的测试。
多查询条件无法整体接收问题的解决
在实际工作中,表单中所给出的查询条件有时是无法将其封装为一个对象的,也就是说,查询方法只能携带多个参数,而不能携带将这多个参数进行封装的一一个对 象。对于这个问题,有两种解决方案。
(1)将这多个参数封装为一个 Map
将这多个参数封装为一个 Map<String,Object>,根据 Map 进行查询。
① 修改 Dao 接口
在 Dao 接口中添加如下方法:
② 修改测试类
③ 修改映射文件
(2)多个参数逐个接收
对于 mapper 中的 SQL 语句,可以通过参数索引 #{index} 的方式逐个接收每个参数。
① 修改 Dao 接口
在 Dao 接口中添加如下方法:
② 修改测试类
③ 修改映射文件