Mybatis实现SQL映射的两种方式
SQL映射是Mybatis中最重要,复杂的组件,它由一个接口和对应的XML文件(或注解)组成。
它可以配置以下内容:
- 描述映射规则。
- 提供 SQL 语句,并可以配置 SQL 参数类型、返回类型、缓存刷新等信息。
- 配置缓存。
- 提供动态 SQL。
在介绍实现映射的方式之前,先用SQL在数据库中创建一个role表。
CREATE TABLE `role` ( `id` BIGINT(20) NOT NULL, `role_name` VARCHAR(20) DEFAULT NULL, `note` VARCHAR(20) DEFAULT NULL, PRIMARY KEY (`id`) )
定义一个POJO,如下所示:
package com.ljt.mybatis; public class Role { private Long id; private String roleName; private String note; }
映射器的主要作用就是将SQL查询到的结果映射为一个POJO,或者将POJO的数据插入到数据库中,并定义一些关于缓存等的重要内容。
注意,开发只是一个接口,而不是一个实现类。
初学者可能会有很大的疑问,接口不是不能运行吗?
是的,接口确实不能直接运行。Mybatis使用了动态代理技术使得接口能够运行起来,目前我们只需要知道Mybatis会为这个接口生成一个代理对象,代理对象会去处理相关的逻辑即可。
一,用XML实现映射器
用 XML 定义映射器分为两个部分:接口和 XML。
先定义一个映射器接口
package com.ljt.mybatis.mapper; import com.ljt.mybatis.bean.Role; public interface RoleMapper { public Role getRole(Long id); }
在XML基础配置文件中写入这样一段代码:
<mapper resource="com/ljt/mybatis/mapper/RoleMapper.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.mybatis.mapper.RoleMapper"> <select id="getRole" parameterType="long" resultType="role"> SELECT id,role_name as roleName,note FROM role WHERE id =#{id} </select> </mapper>
这就完成了一个映射器的定义。
mapper元素中的属性 namespace 所对应的是一个接口的全限定名,于是 MyBatis 上下文就可以通过它找到对应的接口。
select 元素表明这是一条查询语句,而属性 id 标识了这条 SQL所映射的方法名,属性 parameterType=“long” 说明传递给 SQL 的是一个 long 型的参数,而 resultType=“role” 表示返回的是一个 role 类型的返回值。而 role 是之前配置文件 mybatis-config.xml 配置的类的别名,指代的是 com.ljt.mybatis.bean.Role。
这条 SQL 中的 #{id} 表示传递进去的参数。
这里采用的是一种被称为自动映射的功能,MyBatis 在默认情况下提供自动映射,只要 SQL 返回的列名能和 POJO 对应起来即可。
这里 SQL 返回的列名 id 和 note 是可以和之前定义的 POJO 的属性对应起来的,而表里的列 role_name 通过 SQL 别名的改写,使其成为 roleName,也是和 POJO 对应起来的,所以此时 MyBatis 就可以把 SQL 查询的结果通过自动映射的功能映射成为一个 POJO。
二,注解实现映射
除 XML 方式定义映射器外,还可以采用注解方式定义映射器,它只需要一个接口就可以通过 MyBatis 的注解来注入 SQL,如下所示。
package com.ljt.mybatis.mapper; import com.ljt.mybatis.bean.Role; import org.apache.ibatis.annotations.Select; public interface RoleMapper { @Select("select id,role_name as roleName,note from t_role where id=#{id}") public Role getRole(Long id); }
这完全等同于上面使用XML文件方式创建映射器。
目前好像是使用注解映射会比XML映射好用的多(毕竟代码量少很多)。。。
真的是这样吗?
我们来看看以下这条SQL
SELECT .......... From dbo.PDA_TB_Produce a With(Nolock) Join dbo.DctOperationList b With(Nolock) On a.Operation_Code=b.Operation_Code Join dbo.DctOneStatusList c With(Nolock) On a.One_Status_Code=c.One_Status_Code Left join dbo.DctTwoStatusList d With(Nolock) On c.One_Status_Code=d.One_Status_Code and a.Two_Status_Code=d.Two_Status_Code left Join dbo.DctMachineList e With(Nolock) On a.Operation_Code=e.Operation_Code and a.Machine_Code=e.Machine_Code left Join dbo.DctOperationList f With(Nolock) On a.Next_Operation_Code=f.Operation_Code Join dbo.DctUserList g With(Nolock) On a.User_ID_Operating=g.User_ID Join dbo.DctUserList h With(Nolock) On a.User_ID=h.User_ID
emmm…
显然这条 SQL 比较复杂,如果放入 @Select 中会明显增加注解的内容。如果把大量的 SQL 放入 代码中,显然代码的可读性也会下降。
如果同时还要考虑使用动态 SQL, 还需要加入其他的逻辑,这样就使得这个注解更加复杂了,不利于日后的维护和修改。
这时候就会有老实人发问了,那么到底是使用注解还是XML呢?
实际上,注解方式和 XML 方式同时定义时,XML 方式将覆盖掉注解方式,所以 MyBatis 官方推荐使用的是 XML 方式。
此外,XML 可以相互引入,而注解是不可以的,所以在一些比较复杂的场景下,使用 XML 方式会更加灵活和方便。
所以大部分的企业都是以 XML 为主,当然,在一些简单的表和应用中使用注解方式也会比较简单。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持寻技术。