MyBatis Mapper(映射器)

映射器是 MyBatis 中最重要的文件,文件中包含一組 SQL 語(yǔ)句(例如查詢、添加、刪除、修改),這些語(yǔ)句稱為映射語(yǔ)句或映射 SQL 語(yǔ)句。

映射器由 Java 接口和 XML 文件(或注解)共同組成,它的作用如下。

  • 定義參數(shù)類(lèi)型

  • 配置緩存

  • 提供 SQL 語(yǔ)句和動(dòng)態(tài) SQL

  • 定義查詢結(jié)果和 POJO 的映射關(guān)系

映射器有以下兩種實(shí)現(xiàn)方式。

  • 通過(guò) XML 文件方式實(shí)現(xiàn),比如我們?cè)?mybatis-config.xml 文件中描述的 XML 文件,用來(lái)生成 mapper。

  • 通過(guò)注解的方式實(shí)現(xiàn),使用 Configuration 對(duì)象注冊(cè) Mapper 接口。

如果 SQL 語(yǔ)句存在動(dòng)態(tài) SQL 或者比較復(fù)雜,使用注解寫(xiě)在 Java 文件里可讀性差,且增加了維護(hù)的成本。所以一般建議使用 XML 文件配置的方式,避免重復(fù)編寫(xiě) SQL 語(yǔ)句。

XML實(shí)現(xiàn)映射器

XML 定義映射器分為兩個(gè)部分:接口和XML。下面先定義接口 WebsiteMapper(本節(jié)基于《第一個(gè)MyBatis程序》中的示例實(shí)現(xiàn))。。

package net.biancheng.mapper;
import java.util.List;
import net.biancheng.po.Website;
public interface WebsiteMapper {
    public List <Website> selectAllWebsite();
}
                

WebsiteMapper.xml 代碼如下。

<?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="net.biancheng.mapper.WebsiteMapper">

    <!-- 查詢所有網(wǎng)站信息 -->
    <select id="selectAllWebsite"
            resultType="net.biancheng.po.Website">
        select * from website
    </select>

</mapper>
                

下面對(duì)上述 XML 文件進(jìn)行講解。

  • namespace 用來(lái)定義命名空間,該命名空間和定義接口的全限定名一致。

  • <select> 元素表明這是一條查詢語(yǔ)句,屬性 id 用來(lái)標(biāo)識(shí)這條 SQL。resultType 表示返回的是一個(gè) Website 類(lèi)型的值。

在 MyBatis 配置文件中添加以下代碼。

<mapper resource="net/biancheng/mapper/WebsiteMapper.xml" />
                

該語(yǔ)句用來(lái)引入 XML 文件,MyBatis 會(huì)讀取 WebsiteMapper.xml 文件,生成映射器。

下面進(jìn)行測(cè)試,用 SqlSession 來(lái)獲取 Mapper,Test 類(lèi)代碼如下。

public class Test {
    public static void main(String[] args) throws IOException {
        InputStream config = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config);
        SqlSession ss = ssf.openSession();
        WebsiteMapper websiteMapper = ss.getMapper(WebsiteMapper.class);
        List<Website> websitelist = websiteMapper.selectAllWebsite();
        for (Website site : websitelist) {
            System.out.println(site);
        }
        ss.commit();
        ss.close();
    }
}
                

運(yùn)行結(jié)果如下。

DEBUG [main] - ==>  Preparing: select * from website
DEBUG [main] - ==> Parameters:
DEBUG [main] - <==      Total: 1
Website[id=1,name=編程幫,url=http://www.soo66.com/,age=21,country=CN,createtime=Tue Feb 23 10:20:40 CST 2021]
                

注解實(shí)現(xiàn)映射器

使用注解的方式實(shí)現(xiàn)映射器,只需要在接口中使用 Java 注解,注入 SQL 即可。如下所示。

package net.biancheng.mapper;

import java.util.List;
import org.apache.ibatis.annotations.Select;
import net.biancheng.po.Website;

public interface WebsiteMapper2 {
    @Select(value = "select * from website")
    public List<Website> selectAllWebsite();
}
                

這里我們使用了 @Select 注解,并且注入了和 XML 中相同的 select 語(yǔ)句。

如果使用注解和 XML 文件兩種方式同時(shí)定義,那么 XML 方式將覆蓋掉注解方式。

雖然這里注解的方式看起來(lái)比 XML 簡(jiǎn)單,但是現(xiàn)實(shí)中我們遇到的 SQL 會(huì)比該例子復(fù)雜得多。如果 SQL 語(yǔ)句中有多個(gè)表的關(guān)聯(lián)、多個(gè)查詢條件、級(jí)聯(lián)、條件分支等,顯然這條 SQL 就會(huì)復(fù)雜的多,所以并不建議讀者使用這種方式。比如下面這條 SQL。

select * from t_user u
left join t_user_role ur on u.id = ur.user_id
left join t_role r on ur.role_id = r.id
left join t_user_info ui on u.id = ui.user_id
left join t_female_health fh on u.id = fh.user_id
left join t_male_health mh on u.id = mh.user_id
where u.user_name like concat('%', ${userName},'%')
and r.role_name like concat('%', ${roleName},'%')
and u.sex = 1
and ui.head_image is not null;
                

如果把以上 SQL 放到 @Select 注解中,無(wú)疑會(huì)大大降低代碼的可讀性。如果同時(shí)還要考慮使用動(dòng)態(tài) SQL 或需要加入其他的邏輯,這樣就使得這個(gè)注解更加復(fù)雜了,不利于日后的維護(hù)和修改。

此外,XML 可以相互引入,而注解是不可以的,所以在一些比較復(fù)雜的場(chǎng)景下,使用 XML 方式會(huì)更加靈活和方便。因此大部分的企業(yè)都以 XML 為主,本教程也會(huì)保持一致,以 XML 方式來(lái)創(chuàng)建映射器。當(dāng)然在一些簡(jiǎn)單的表和應(yīng)用中使用注解方式也會(huì)比較簡(jiǎn)單。

這個(gè)接口可以在 XML 中定義,將在 mybatis-config.xml 中配置 XML 的語(yǔ)句修改為以下語(yǔ)句即可。

<mapper resource="com/mybatis/mapper/WebsiteMapper2" />
                

也可以使用 configuration 對(duì)象注冊(cè)這個(gè)接口,比如:

configuration.addMapper(WebsiteMapper2.class);
                

MyBatis 映射器的主要元素

下面介紹在映射器中可以定義哪些元素,以及它們的作用。

元素名稱 描述 備注
mapper 映射文件的根節(jié)點(diǎn),只有 namescape 一個(gè)屬性 namescape 作用如下:①用于區(qū)分不同的 mapper,全局唯一②綁定DAO接口,即面向接口編程。當(dāng) namescape 綁定某一接口后,可以不用寫(xiě)該接口的實(shí)現(xiàn)類(lèi),MyBatis 會(huì)通過(guò)接口的完整限定名查找到對(duì)應(yīng)的 mapper 配置來(lái)執(zhí)行 SQL 語(yǔ)句。因此 namescape 的命名必須要跟接口同名。
select 查詢語(yǔ)句,最常用、最復(fù)雜的元素之一 可以自定義參數(shù),返回結(jié)果集等
insert 插入語(yǔ)句 執(zhí)行后返回一個(gè)整數(shù),代表插入的條數(shù)
update 更新語(yǔ)句 執(zhí)行后返回一個(gè)整數(shù),代表更新的條數(shù)
delete 刪除語(yǔ)句 執(zhí)行后返回一個(gè)整數(shù),代表刪除的條數(shù)
parameterMap 定義參數(shù)映射關(guān)系 即將被刪除的元素,不建議使用
sql 允許定義一部分的 SQL,然后在各個(gè)地方引用它 例如,一張表列名,我們可以一次定義,在多個(gè) SQL 語(yǔ)句中使用
resultMap 用來(lái)描述數(shù)據(jù)庫(kù)結(jié)果集與對(duì)象的對(duì)應(yīng)關(guān)系,它是最復(fù)雜、最強(qiáng)大的元素 提供映射規(guī)則
cache 配置給定命名空間的緩存 -
cache-ref 其它命名空間緩存配置的引用 -

后面文章中會(huì)詳細(xì)介紹以上元素。

拓展

關(guān)于 MyBatis 的 SQL 映射文件中的 mapper 元素的 namescape 屬性有如下要求。

  • namescape 的命名必須跟某個(gè) DAO 接口同名,同屬于 DAO 層,因此代碼結(jié)構(gòu)上,映射文件與該接口應(yīng)放置在同一 package 下(如 net.biancheng.dao.website),并且習(xí)慣上是以 Mapper 結(jié)尾(如 WebsiteMapper.java、WebsiteMapper.xml)。

  • 不同的 mapper 文件中子元素的 id 可以相同,MyBatis 通過(guò) namescape 和子元素的 id 聯(lián)合區(qū)分。接口中的方法與映射文件中的 SQL 語(yǔ)句 id 應(yīng)一 一對(duì)應(yīng)。

丰满人妻一级特黄a大片,午夜无码免费福利一级,欧美亚洲精品在线,国产婷婷成人久久Av免费高清