MyBatis Mapper(映射器)
映射器由 Java 接口和 XML 文件(或注解)共同组成,它的作用如下。
定义参数类型
配置缓存
提供 SQL 语句和动态 SQL
定义查询结果和 POJO 的映射关系
映射器有以下两种实现方式。
通过 XML 文件方式实现,比如我们在 mybatis-config.xml 文件中描述的 XML 文件,用来生成 mapper。
通过注解的方式实现,使用 Configuration 对象注册 Mapper 接口。
如果 SQL 语句存在动态 SQL 或者比较复杂,使用注解写在 Java 文件里可读性差,且增加了维护的成本。所以一般建议使用 XML 文件配置的方式,避免重复编写 SQL 语句。
XML实现映射器
XML 定义映射器分为两个部分:接口和XML。下面先定义接口 WebsiteMapper(本节基于《个MyBatis程序》中的示例实现)。
package net.biancheng.mapper;
import java.util.List;
import net.biancheng.po.Website;
public interface WebsiteMapper {
public List<Website> selectAllWebsite();
}
WebsiteMapper.xml 代码如下。
该语句用来引入 XML 文件,MyBatis 会读取 WebsiteMapper.xml 文件,生成映射器。<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis网站站点" rel="nofollow" />
<mapper resource="net/biancheng/mapper/WebsiteMapper.xml" />
下面进行测试,用 SqlSession 来获取 Mapper,Test 类代码如下。
这里我们使用了 @Select 注解,并且注入了和 XML 中相同的 select 语句。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);
}
s网站站点" rel="nofollow" />
DEBUG [main] - ==> Preparing: select * from website
DEBUG [main] - ==> Parameters:
DEBUG [main] - <== Total: 1Website[id=1,name=编程帮,url=https://www.biancheng网站站点" rel="nofollow" />
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();
}
如果使用注解和 XML 文件两种方式同时定义,那么 XML 方式将覆盖掉注解方式。
虽然这里注解的方式看起来比 XML 简单,但是现实中我们遇到的 SQL 会比该例子复杂得多。如果 SQL 语句中有多个表的关联、多个查询条件、级联、条件分支等,显然这条 SQL 就会复杂的多,所以并不建议读者使用这种方式。比如下面这条 SQL。
如果把以上 SQL 放到 @Select 注解中,无疑会大大降低代码的可读性。如果同时还要考虑使用动态 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;
此外,XML 可以相互引入,而注解是不可以的,所以在一些比较复杂的场景下,使用 XML 方式会更加灵活和方便。因此大部分的企业都以 XML 为主,本教程也会保持一致,以 XML 方式来创建映射器。当然在一些简单的表和应用中使用注解方式也会比较简单。
这个接口可以在 XML 中定义,将在 mybatis-config.xml 中配置 XML 的语句修改为以下语句即可。
<mapper resource="com/mybatis/mapper/WebsiteMapper2" />
也可以使用 configuration 对象注册这个接口,比如:
configuration.addMapper(WebsiteMapper2.class);
MyBatis 映射器的主要元素
下面介绍在映射器中可以定义哪些元素,以及它们的作用。元素名称 | 描述 | 备注 |
---|---|---|
mapper | 映射文件的根节点,只有 namescape 一个属性 | namescape 作用如下:
|
select | 查询语句,最常用、最复杂的元素之一 | 可以自定义参数,返回结果集等 |
insert | 插入语句 | 执行后返回一个整数,代表插入的条数 |
update | 更新语句 | 执行后返回一个整数,代表更新的条数 |
delete | 删除语句 | 执行后返回一个整数,代表删除的条数 |
parameterMap | 定义参数映射关系 | 即将被删除的元素,不建议使用 |
sql | 允许定义一部分的 SQL,然后在各个地方引用它 | 例如,一张表列名,我们可以一次定义,在多个 SQL 语句中使用 |
resultMap | 用来描述数据库结果集与对象的对应关系,它是最复杂、最强大的元素 | 提供映射规则 |
cache | 配置给定名空间的缓存 | - |
cache-ref | 其它名空间缓存配置的引用 | - |
后面文章中会详细介绍以上元素。
拓展
关于 MyBatis 的 SQL 映射文件中的 mapper 元素的 namescape 属性有如下要求。
namescape 的名必须跟某个 DAO 接口同名,同属于 DAO 层,因此代码结构上,映射文件与该接口应放置在同一 package 下(如 net.biancheng.dao.website),并且习惯上是以 Mapper 结尾(如 WebsiteMapper.java、WebsiteMapper.xml)。
不同的 mapper 文件中子元素的 id 可以相同,MyBatis 通过 namescape 和子元素的 id 联区分。接口中的方法与映射文件中的 SQL 语句 id 应一 一对应。