使用XML方式
MyBatis 的真正强大之处在于它的映射语句,这也是它的魔力所在。由于它的映射语句异常强大,映射器的 XML 文件就显得相对简单。如果将其与具有相同功能的 JDBC 代码进行对比,立刻就会发现,使用这种方法节省了将近 95% 的代码量。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。
MyBatis 3.0 相比 2.0 版本的一个最大变化,就是支持使用接口来调用方法。
以前使用 SqlSession 通过命名空间调用 MyBatis 方法时,首先需要用到命名空间和方法 id 组成的字符串来调用相应的方法。当参数多于 1 个的时候,需要将所有参数放到一个 Map 对象中。通过 Map 传递多个参数,使用起来很不方便,而且还无法避免很多重复的代码。
使用接口调用方式就会方便很多,MyBatis 使用 Java 的动态代理可以直接通过接口来调用相应的方法,不需要提供接口的实现类,更不需要在实现类中使用 SqlSession 以通过命名空间间接调用。另外,当有多个参数的时候,通过参数注解 @Param 设置参数的名字省去了手动构造 Map 参数的过程,尤其在 Spring 中使用的时候,可以配置为自动扫描所有的接口类,直接将接口注入需要用到的地方。这些内容会在后面的章节中讲到,现在不能理解也没有关系。
因为使用接口更方便,而且它已被广泛使用,因此本书中会主要使用接口调用的方式,同时也会提供一些 SqlSession 方式调用的例子来帮助大家理解 MyBatis。
MyBatis 注解的使用方法会在下一章中讲到,大家不要认为使用接口就是使用了 MyBatis 注解,这两者是不同的。 接口可以配合 XML 使用,也可以配合注解来使用。XML 可以单独使用,但是注解必须在接口中使用。 |
话不多说,接下来看一看如何使用 MyBatis 的 XML 方式。
首先,在 src/main/resources 的 tk.mybatis.simple.mapper 目录下创建 5 个表各自对应的 XML 文件,分别为 UserMapper.xml、RoleMapper.xml、PrivilegeMapper.xml、UserRoleMapper.xml 和 RolePrivilegeMapper.xml。然后,在 src/main/java 下面创建包 tk.mybatis.simple.mapper。接着,在该包下创建 XML 文件对应的接口类,分别为 UserMapper.java、RoleMapper.java、PrivilegeMapper.java、UserRoleMapper.java 和 RolePrivilegeMapper.java。
Mapper.xml 文件如何写,大家在第一章应该已经有所了解。下面以用户表对应的 Mapper 接口 UserMapper.java 为例进行说明。
package cn.liaozh.mybatis2.ch2.xml.mapper;
public interface UserMapper {
}
到目前为止,Mapper 接口和对应的 XML 文件都是空的,后续会逐步添加接口方法。创建完所有文件后,打开 UserMapper.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="cn.liaozh.mybatis2.ch2.xml.mapper.UserMapper">
</mapper>
需要注意的是 <mapper> 根标签的 namespace 属性。当 Mapper 接口和 XML 文件关联的时候,命名空间 namespace 的值就需要配置成接口的全限定名称,例如 UserMapper 接口对应的 tk.mybatis.simple.mapper.UserMapper,MyBatis 内部就是通过这个值将接口和 XML 关联起来的。更详细的原理会在下一节配合简单的例子进行讲解。按照相同的方式将另外 4 个 Mapper.xml 文件写完。准备好这几个 XML 映射文件后,还需要在 1.3.2 节中创建的 mybatis-config.xml 配置文件中的 mappers 元素中配置所有的 mapper,部分配置代码如下。
<mappers>
<mapper resource="cn.liaozh.mybatis2.ch2.xml.mapper.UserMapper.xml" />
<mapper resource="cn.liaozh.mybatis2.ch2.xml.mapper.RoleMapper.xml" />
<mapper resource="cn.liaozh.mybatis2.ch2.xml.mapper.PrivilegeMapper.xml" />
<mapper resource="cn.liaozh.mybatis2.ch2.xml.mapper.UserRoleMapper.xml" />
<mapper resource="cn.liaozh.mybatis2.ch2.xml.mapper.RolePrivilegeMapper.xml" />
</mappers>
这种配置方式需要将所有映射文件一一列举出来,如果增加了新的映射文件,还需要注意在此处进行配置,操作起来比较麻烦。因为此处所有的 XML 映射文件都有对应的 Mapper 接口,所以还有一种更简单的配置方式,代码如下。
<mappers>
<package name="cn.liaozh.mybatis2.ch2.xml.mapper"/>
</mappers>
这种配置方式会先查找 tk.mybatis.simple.mapper 包下所有的接口,循环对接口进行如下操作。
-
判断接口对应的命名空间是否已经存在,如果存在就抛出异常,不存在就继续进行接下来的操作。
-
加载接口对应的 XML 映射文件,将接口全限定名转换为路径,例如,将接口 tk.mybatis.simple.mapper.UserMapper 转换为 tk/mybatis/simple/mapper/UserMapper.xml,以
.xml
为后缀搜索 XML 资源,如果找到就解析 XML。 -
处理接口中的注解方法。
因为这里的接口和 XML 映射文件完全符合上面操作的第 2 点,因此直接配置包名就能自动扫描包下的接口和 XML 映射文件,省去了很多麻烦。准备好这一切后就可以开始学习具体的用法了。