Mybatis映射原理

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 包下所有的接口,循環對接口進行判斷接口對應的命名 空 間是否己經存在,如果不存在就拋出異常,存在就繼續進行接下來的操作。加載接口對應的卻也映射文件 , 將接口全限定名轉換爲路徑.
爲什麼 Mapper 接口沒有實現類卻能被正常調用呢?
這是因爲MyBaits 在 Mapper 接口上使用了動態代理的一種非常規的用法,熟悉這動態代理的用法不僅有利於理解 MyBatis 接口和 XML 的關係,還能開闊思路 。

從代理類中可以看到,當調用 一個接口的方法時,會先通過接口的全限定名稱和當前調用的方法名的組合得到一個方法 id,這個 id 的值就是映射 XML 中口arnespa ce 和具體方法 id的組合。所以可以在代理方法中使用 sqlSession 以命名空間的方式調用方法。通過這種方式可以將接口和 XML 文件中的方法關聯起來。這種代理方式和常規代理的不同之處在於,這裏沒有對某個具體類進行代理,而是通過代理轉化成了對其他代碼的調用。

由於方法參數和返回值存在很多種情況,因此 MyBatis 的內部實現會比上面的邏輯複雜得多,正是因爲 MyBatis 對接口動態代理的實現,我們在使用接口方式的時候纔會如此容易。

發佈了129 篇原創文章 · 獲贊 31 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章