MyBatis 的真正強大之處在于它的映射語句,這也是它的魔力所在。由于它的映射語句異
常強大,映射器的 XML 文件就顯得相對簡單。
MyBatis 3.0 相比 2.0 版本的一個最大變化,就是支持使用接口來調用方法。
以前使用 SqlSession 通過命名空間調用 MyBatis 方法時,首先需要用到命名空間和方法
id 組成的字符串來調用相應的方法 。 當參數多于 1 個的時候,需要將所有參數放到一個 Map
對象中 。 通過 Map 傳遞多個參數,使用起來很不方便,而且還無法避免很多重復的代碼。
使用接口調用方式就會方便很多, MyBatis 使用 Java 的動態代理可以直接通過接口來調
用 相應 的方法,不需要提供接口的實現類,更不需要在實現類中使用 SqlSess 工∞以通過
命名空 間間接調用 。 另外,當有多個參數的時候,通過參數注解@ Par am 設置參數的名字省
去了 手動構造 Map 參數的過程,尤其在 Spring 中使用的時候,可以配置為自動掃描所有的
接口類 ,直接將接口注入需要用到的地方。
mapper文件示例:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cnpiec.ireader.dao.GetBookDataDao">
<insert id="batchInsertBook" parameterType="Book">
INSERT INTO BOOK (BOOKID,NAME,PARTNERNAME) VALUES
<foreach collection="list" item="book" separator=",">
(#{book.bookId}, #{book.name}, #{book.partnerName})
</foreach>
</insert>
</mapper>
需要注意的是<mapper>根標簽的 name space 屬性。當 Mapper 接口和 XML 文件關聯的
時候,命名空間口amespace 的值就需要配置成接口的全限定名稱,例如 UserMapper 接口對
應的 tk. mybatis . simple .mapper . UserMapper, MyBatis 內部就是通過這個值將接口和
XML 關聯起來的。
mybati s-config.xml 配置文件中的 mappers 元素中配置所有的 mapper ,部分配置代碼如下 。
<mappers>
<mapper resource=” tk/mybatis/simple/mapper/CountryMapper.xml ” / >
<mapper resource=” tk/mybatis/simple/mapper/UserMapper . xml ” / >
<mapper resource=” tk/mybatis/simple/mapper/RoleMapper.xml ” />
<mapper resource=” tk/mybatis/simple/mapper/PrivilegeMapper . xml ” />
<mapper resource=” tk/mybatis/simple/mapper/UserRoleMapper . xml ” />
<mapper resource=” tk/mybatis/simple/mapper / RolePrivilegeMapper.xml ” />
</mappers>
更簡單的配置方式,代碼如下
<mappers>
<package name= ” tk.mybatis . simple . mapper ” />
</mappers>
這種配置方式會先查找 tk.mybatis.simple . mapper 包下所有的接口,循環對接口進行
如下操作。
這種配置方式會先查找 tk.mybatis.simple . mapper 包下所有的接口,循環對接口進行
如下操作。
- 判斷接口對應的命名 空 間是否己經存在,如果不存在就拋出異常,存在就繼續進行接下
來的操作。 - 加載接口對應的卻也映射文件 , 將接口全限定名轉換為路徑 , 例如 , 將接口
tk.mybatis.simple.mapper.UserMapper 轉換為 tk/mybati s/simple/mapper/UserMapper.xml,
搜索以.xml 為后綴搜索 XML 資源,如果找到就解析 XML 。 - 處理接口中的注解方法。
為什么 Mapper 接口沒有實現類卻能被正常調用呢?
這是因為 MyBaits 在 Mapper 接口上使用了動態代理的一種非常規的用法,熟悉這種動態代
理的用法不僅有利于理解 MyBatis 接口和 XML 的關系,還能開闊思路 。
從代理類中可以看到,當調用 一個接口的方法時,會先通過接口的全限定名稱和當前調用
的方法名的組合得到一個方法 id,這個 id 的值就是映射 XML 中口arnespa ce 和具體方法 id
的組合。所以可以在代理方法中使用 sqlSession 以命名空間的方式調用方法。通過這種方式
可以將接口和 XML 文件中的方法關聯起來。這種代理方式和常規代理的不同之處在于,這里
沒有對某個具體類進行代理,而是通過代理轉化成了對其他代碼的調用。
由于方法參數和返回值存在很多種情況,因此 MyBatis 的內部實現會比上面的邏輯復雜得
多,正是因為 MyBatis 對接口動態代理的實現,我們在使用接口方式的時候才會如此容易。如
果大家對 MyBatis 源碼感興趣,可以通過第 11 章的內容了解 MyBatis 的源碼并深入學習。
通過本節這個簡單的例子,我們可以了解 MyBatis 動態代理實現的方式,同時也學會一種
編程思路:可以通過動態代理這個橋梁將對接口方法的調用轉換為對其他方法的調用 。