映射器是 MyBatis 中最重要、最复杂的组件,它由一个接口和对应的 XML 文件(或注解)组成,它可以配置以下内容:
- 描述映射规则
- 提供SQL 语句,并可以配置 SQL 参数类型、返回类型、缓存刷新等信息
- 配置缓存
本次讲述两种实现映射器的方式,XML 文件形式和注解形式。在此之前,先定义一个 POJO。
定义 POJO
package com.learn.ssm.chapter1.pojo;
public class Role{
private Long id;
private String roleName;
private String note;
public Long getId(){
return id;
}
public void setId(Long id){
this.id = id;
}
public String getRoleName(){
return roleName;
}
public void setRoleName(String roleName){
this.roleName = roleName;
}
public String getNote(){
return note;
}
public void setNote(String note){
this.note = note;
}
}
映射器的主要作用就是将 SQL 查询到的结果映射为一个 POJO,或者将 POJO 的数据插入到数据库中,并定义一些关于缓存等的重要内容。
注意,此时编写的只是一个接口,并不是一个实现类。接口不能直接运行,但是 MyBatis 运用了动态代理技术使接口能够运行起来,MyBatis 会为这个接口生成一个代理对象,代理对象会去处理相关的逻辑。
一、用 XML 实现映射器
用 XML 定义映射器分为两个部分:接口和 XML 。先定义一个映射器接口,代码如下:
映射器接口
package com.learn.ssm.chapter1.mapper;
public interface RoleMapper{
public Role getRole(Long id);
}
在用 XML 方式创建 SqlSession 的配置文件时,有这样一段代码:
<mapper resource="com/learn/ssm/chapter1/mapper/RoleMapper.xml"/>
它的作用就是引入一个 XML 文件。
用 XML 方式创建映射器,代码如下:
用 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="com.learn.ssm.chapter1.mapper.RoleMapper">
<select id="getRole" parameterType="long" resultType="role">
select id,role_name,note as id,roleName,note from t_role where id=#{id}
</select>
</mapper>
有了这两个文件,就完成了一个映射器的定义。XML 文件简述:
- <mapper> 元素中的属性 namespace 所对应的是一个接口的全限定名,于是 MyBatis 上下文就可以通过它找到对应的接口。
- <select> 元素表明这是一条查询语句,而属性 id 标识了这条 SQL,属性 parameterType="long" 说明传递给 SQL 的是一个 long 类型的参数,而 resultType="role" 表示返回的是一个 role 类型的返回值。而 role 是在之前配置文件 mybatis-config.xml 配置的别名,指代的是 com.learn.ssm.chapter1.pojo.Role。(<typeAliases><typeAlias alias="role" type="com.learn.ssm.chapter1.pojo.Role"/><typeAliases>)
- 这条 SQL 中的 #{id} 表示传递进去的参数。
注意,这里我们并没有配置 SQL 执行后和 role 的对应关系,采用的是一种被称为自动映射的功能。MyBatis 在默认情况下提供自动映射,只要 SQL 返回的列名能和 POJO 对应起来即可。这里 SQL 返回的 id、role_name 、note 是可以和 POJO 的属性对应起来的,而且表里的列名 role_name 通过 SQL 别名的改写,使其成为 roleName,这样就使其和 POJO 属性对应起来,所以此时 MyBatis 就可以把 SQL 查询的结果通过自动映射的功能映射成为一个 POJO。
二、注解实现映射器
除 XML 方式定义映射器外,还可以采用注解方式定义映射器,它只需要一个接口就可以通过 MyBatis 的注解来注入 SQL,代码如下:
通过注解实现映射器
import com.learn.ssm.chapter1.pojo.Role;
public interface RoleMapper2{
@Select("select id,role_name as roleName,note from t_role where id=#{id})
public Role getRole(Long id);
}
这完全等同于 XML 方式创建映射器。如果它和 XML 方式同时定义,XML 方式将会覆盖掉注解方式,所以 MyBatis 官方推荐使用 XML 方式。此外,XML 方式可以相互引入,而注解是不可以的,所以在复杂场景下,使用 XML 方式会更加灵活和方便。
三、发送 SQL
1.SqlSession 发送 SQL
有了映射器就可以通过 SqlSession 发送 SQL 了。我们以 getRole (事先在 XML 映射文件定义好的,id 为 getRole)这条 SQL 为例,看看如何发送 SQL。
Role role = (Role)sqlSession.selectOne("com.learn.ssm.chapter1.mapper.RoleMapper.getRole",1L);
selectOne 方法表示使用查询并且只返回一个对象,参数是一个 String 对象和一个 Object 对象。String 对象是由一个命名空间加上 SQL id 组合而成的,它完全定位了一定 SQL ,这样MyBatis 就会找到对应的 SQL。如果在 MyBatis 中只有一个 id 为 getRole 的 SQL ,那么也可以简写为:
Role role = (Role)sqlSession.selectOne("getRole",1L);
这是 MyBatis 前身 iBatis 所留下的方式。第二个参数是一个 long 参数,long 参数是它的主键。
2.用 Mapper 接口发送 SQL
SqlSession 还可以获取 Mapper 接口,通过 Mapper 接口发送 SQL ,代码如下:
用 SqlSession 获取 Mapper 接口,并发送 SQL
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Role role = roleMapper.getRole(1L);
通过 SqlSession 的 getMapper 方法来获取一个 Mapper 接口,就可以调用它的方法了。因为 XML 文件或者接口注解定义的 SQL 都可以通过“类的全限定名+方法名”查找,所以 MyBatis 会启用对应的 SQL 进行运行,并返回结果。