目录
一、引言
最近重构了一次Mybatis mapper.xml中的sql定义,涉及的table包括system_func_operation, system_func, system_func_group,sql定义了3个table的连接查询,并通过resultMap定义了数据库column和Java对象的property映射,需要映射的Java对象结构如下:
//FuncOperationVo - 通过resultmap定义列转换
{
"id": "32901",
"opName": "新增",
"opCode": "add",
"sortNum": 1,
"remarks": "备注",
"enabled": 1,
"createUser": "admin",
"createTime": "2023-06-14 10:37:54",
"modifyUser": "admin",
"modifyTime": "2023-06-14 10:37:57",
"enableFlag": "0",
//FuncGroupVo - 通过resultmap中的association定义嵌套对象列转换
"funcGroup": {
"id": "30901",
"groupName": "功能组A",
"groupType": 1,
"sortNum": 1,
"remarks": null,
"createUser": "admin",
"createTime": "2022-08-24 09:04:43",
"modifyUser": "admin",
"modifyTime": "2023-04-19 15:06:23",
"enableFlag": null
},
//FuncVo - 通过resultmap中的association定义嵌套对象列转换
"func": {
"id": "31901",
"funcName": "系统API",
"funcCode": "system_api",
"entryPageUrl": null,
"sortNum": 3,
"remarks": "备注",
"enabled": 1,
"funcGroup": null,
"createUser": "admin",
"createTime": "2023-04-18 13:25:38",
"modifyUser": "admin",
"modifyTime": "2023-04-18 14:39:05",
"enableFlag": "0"
}
}
FuncOperationMapper.xml中sql定义如下,
<?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.luo.demo.dao.FuncOperationMapper">
<!-- FuncOperationVo映射结果 -->
<resultMap id="FuncOperationVoResultMap" type="com.luo.demo.vo.FuncOperationVo">
<id column="id" property="id" />
<result column="op_name" property="opName" />
<result column="op_code" property="opCode" />
<result column="sort_num" property="sortNum" />
<result column="remarks" property="remarks" />
<result column="enabled" property="enabled" />
<result column="create_user" property="createUser" />
<result column="create_time" property="createTime" />
<result column="modify_user" property="modifyUser" />
<result column="modify_time" property="modifyTime" />
<result column="enable_flag" property="enableFlag" />
<!-- FuncVo嵌套对象列转换 -->
<association property="func">
<id column="id" property="id" />
<result column="f_func_name" property="funcName" />
<result column="f_func_code" property="funcCode" />
<result column="f_entry_page_url" property="entryPageUrl" />
<result column="f_sort_num" property="sortNum" />
<result column="f_remarks" property="remarks" />
<result column="f_enabled" property="enabled" />
<result column="f_create_user" property="createUser" />
<result column="f_create_time" property="createTime" />
<result column="f_modify_user" property="modifyUser" />
<result column="f_modify_time" property="modifyTime" />
<result column="f_enable_flag" property="enableFlag" />
</association>
<!-- FuncGroupVo嵌套对象列转换 -->
<association property="funcGroup">
<id column="fg_id" property="id" />
<result column="fg_group_name" property="groupName" />
<result column="fg_group_type" property="groupType" />
<result column="fg_sort_num" property="sortNum" />
<result column="fg_remarks" property="remarks" />
<result column="fg_create_user" property="createUser" />
<result column="fg_create_time" property="createTime" />
<result column="fg_modify_user" property="modifyUser" />
<result column="fg_modify_time" property="modifyTime" />
<result column="fg_enable_flag" property="enableFlag" />
</association>
</resultMap>
<!-- 根据功能ID查询功能详情(包括所属功能组信息) - 3个table的连接查询 -->
<select id="getFuncVoById" resultMap="FuncVoResultMap">
select
<!-- funcOperation操作相关列 -->
fo.id,
fo.op_name,
fo.op_code,
fo.sort_num,
fo.remarks,
fo.enabled,
fo.create_user,
fo.create_time,
fo.modify_user,
fo.modify_time,
fo.enable_flag,
<!-- func相关列表 -->
f.id as f_id,
f.func_name as f_func_name,
f.func_code as f_func_code,
f.entry_page_url as f_entry_page_url,
f.sort_num as f_sort_num,
f.remarks as f_remarks,
f.enabled as f_enabled,
f.create_user as f_create_user,
f.create_time as f_create_time,
f.modify_user as f_modify_user,
f.modify_time as f_modify_time,
f.enable_flag as f_enable_flag,
<!-- funcGroup相关列 -->
fg.id as fg_id,
fg.group_name as fg_group_name,
fg.group_type as fg_group_type,
fg.sort_num as fg_sort_num,
fg.remarks as fg_remarks,
fg.create_user as fg_create_user,
fg.create_time as fg_create_time,
fg.modify_user as fg_modify_user,
fg.modify_time as fg_modify_time,
fg.enable_flag as fg_enabled_flag
from system_func_operation fo
left join system_func f on f.id = fo.func_id and f.enable_flag = 0
left join system_func_group fg on fg.id = fo.func_group_id and fg.enable_flag = 0
<where>
fo.id = #{id}
and fo.enable_flag = 0
</where>
</select>
</mapper>
二、使用resultMap.extends复用原有resultMap定义
比如原来在FuncOperationMapper.xml中已经有了基础的resultMap定义,则可以通过resultMap.extends复用原有的resultMap定义,如此便避免了resultMap中列的重复定义,具体调整如下:
<?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.luo.demo.dao.FuncOperationMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.luo.demo.entity.FuncOperation">
<id column="id" property="id" />
<result column="op_name" property="opName" />
<result column="op_code" property="opCode" />
<result column="func_group_id" property="funcGroupId" />
<result column="func_id" property="funcId" />
<result column="sort_num" property="sortNum" />
<result column="remarks" property="remarks" />
<result column="enabled" property="enabled" />
<result column="create_user" property="createUser" />
<result column="create_time" property="createTime" />
<result column="modify_user" property="modifyUser" />
<result column="modify_time" property="modifyTime" />
<result column="enable_flag" property="enableFlag" />
</resultMap>
<!-- FuncOperationVo映射结果(注意此处resultMap.extends继承了之前的BaseResultMap列定义) -->
<resultMap id="FuncOperationVoResultMap" type="com.luo.demo.vo.FuncOperationVo" extends="BaseResultMap">
<association property="func">
<id column="id" property="id" />
<result column="f_func_name" property="funcName" />
<result column="f_func_code" property="funcCode" />
<result column="f_entry_page_url" property="entryPageUrl" />
<result column="f_sort_num" property="sortNum" />
<result column="f_remarks" property="remarks" />
<result column="f_enabled" property="enabled" />
<result column="f_create_user" property="createUser" />
<result column="f_create_time" property="createTime" />
<result column="f_modify_user" property="modifyUser" />
<result column="f_modify_time" property="modifyTime" />
<result column="f_enable_flag" property="enableFlag" />
</association>
<association property="funcGroup">
<id column="fg_id" property="id" />
<result column="fg_group_name" property="groupName" />
<result column="fg_group_type" property="groupType" />
<result column="fg_sort_num" property="sortNum" />
<result column="fg_remarks" property="remarks" />
<result column="fg_create_user" property="createUser" />
<result column="fg_create_time" property="createTime" />
<result column="fg_modify_user" property="modifyUser" />
<result column="fg_modify_time" property="modifyTime" />
<result column="fg_enable_flag" property="enableFlag" />
</association>
</resultMap>
......
</mapper>
三、使用association.resultMap、association.columnPrefix复用原有resultMap定义
注:
collection标签拥有相同resultMap、columnPrefix属性,具体使用可参见association使用。
若association对应的对象类型已存在resultMap定义,则可通过association.resultMap属性直接使用原有的resultMap列定义,同时可通过association.columnPrefix来统一设置result.column的别名前缀,具体调整如下:
<?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.luo.demo.dao.FuncOperationMapper">
<!-- FuncOperation通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.luo.demo.entity.FuncOperation">
<id column="id" property="id" />
<result column="op_name" property="opName" />
<result column="op_code" property="opCode" />
<result column="func_group_id" property="funcGroupId" />
<result column="func_id" property="funcId" />
<result column="sort_num" property="sortNum" />
<result column="remarks" property="remarks" />
<result column="enabled" property="enabled" />
<result column="create_user" property="createUser" />
<result column="create_time" property="createTime" />
<result column="modify_user" property="modifyUser" />
<result column="modify_time" property="modifyTime" />
<result column="enable_flag" property="enableFlag" />
</resultMap>
<!-- FuncVo查询映射结果 -->
<resultMap id="FuncVoResultMap" type="com.luo.demo.vo.FuncVo">
<id column="id" property="id" />
<result column="func_name" property="funcName" />
<result column="func_code" property="funcCode" />
<result column="func_group_id" property="funcGroupId" />
<result column="entry_page_url" property="entryPageUrl" />
<result column="sort_num" property="sortNum" />
<result column="remarks" property="remarks" />
<result column="enabled" property="enabled" />
<result column="create_user" property="createUser" />
<result column="create_time" property="createTime" />
<result column="modify_user" property="modifyUser" />
<result column="modify_time" property="modifyTime" />
<result column="enable_flag" property="enableFlag" />
</resultMap>
<!-- FuncGroupVo查询映射结果 -->
<resultMap id="FuncGroupVoResultMap" type="com.luo.demo.vo.FuncGroupVo">
<id column="id" property="id" />
<result column="group_name" property="groupName" />
<result column="group_type" property="groupType" />
<result column="sort_num" property="sortNum" />
<result column="remarks" property="remarks" />
<result column="create_user" property="createUser" />
<result column="create_time" property="createTime" />
<result column="modify_user" property="modifyUser" />
<result column="modify_time" property="modifyTime" />
<result column="enable_flag" property="enableFlag" />
</resultMap>
<!-- FuncOperationVo映射结果 -->
<resultMap id="FuncOperationVoResultMap" type="com.luo.demo.vo.FuncOperationVo" extends="BaseResultMap">
<!-- 注意此处使用association.resultMap复用了原有的resultMap定义, -->
<!-- 同时使用association.columnPrefix来统一设置result.column的别名前缀 -->
<association property="func" columnPrefix="f_" resultMap="FuncVoResultMap"/>
<association property="funcGroup" columnPrefix="fg_" resultMap="FuncGroupVoResultMap"/>
</resultMap>
......
</mapper>
四、使用sql自定义参数支持columns定义复用
重构完resultmap,接下来重构sql定义。
通常mapper.xml中都会习惯定义Base_Column_List,包括table中的所有列,然后使用<inclucde refid="...”/>
引用对应的sql.id即可在mapper.xml中复用此sql定义:
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
op_name,
op_code,
sort_num,
remarks,
enabled,
create_user,
create_time,
modify_user,
modify_time,
enable_flag
</sql>
而本例sql中列都有table别名前缀,如fo.op_name
,同时列名称还会被转换为带前缀的名称,如fo.op_name as fo_op_name
,
可将本例中sql的列定义格式抽象为:表名前缀_列名 as 列名前缀_列名
,可通过Mybatis中<sql id="..."/>
标签支持自定义参数${参数名}
的机制,为<sql/>
中的列定义表名前缀参数${alias}
、列名前缀参数${prefix}
,然后在使用<inclucde refid="...”/>
引用sql时可通过<property name="alias" value="..."/>
、<property name="prefix" value="..."/>
设置对应的参数值,具体调整如下:
<?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.luo.demo.dao.FuncOperationMapper">
......
<!-- FuncOperation通用查询结果列 - 定义 表名前缀参数${alias}、列名前缀参数${prefix} -->
<sql id="Operation_Base_Column_List">
${alias}id as ${prefix}id,
${alias}op_name as ${prefix}op_name,
${alias}op_code as ${prefix}op_code,
${alias}sort_num as ${prefix}sort_num,
${alias}remarks as ${prefix}remarks,
${alias}enabled as ${prefix}enabled,
${alias}create_user as ${prefix}create_user,
${alias}create_time as ${prefix}create_time,
${alias}modify_user as ${prefix}modify_user,
${alias}modify_time as ${prefix}modify_time,
${alias}enable_flag as ${prefix}enable_flag
</sql>
<!-- Func通用查询结果列 - 定义 表名前缀参数${alias}、列名前缀参数${prefix} -->
<sql id="Func_Base_Column_List">
${alias}id as ${prefix}id,
${alias}func_name as ${prefix}func_name,
${alias}func_code as ${prefix}func_code,
${alias}entry_page_url as ${prefix}entry_page_url,
${alias}sort_num as ${prefix}sort_num,
${alias}remarks as ${prefix}remarks,
${alias}enabled as ${prefix}enabled,
${alias}create_user as ${prefix}create_user,
${alias}create_time as ${prefix}create_time,
${alias}modify_user as ${prefix}modify_user,
${alias}modify_time as ${prefix}modify_time,
${alias}enable_flag as ${prefix}enable_flag
</sql>
<!-- FuncGroup通用查询结果列 - 定义 表名前缀参数${alias}、列名前缀参数${prefix} -->
<sql id="Group_Base_Column_List">
${alias}id as ${prefix}id,
${alias}group_name as ${prefix}group_name,
${alias}group_type as ${prefix}group_type,
${alias}sort_num as ${prefix}sort_num,
${alias}remarks as ${prefix}remarks,
${alias}create_user as ${prefix}create_user,
${alias}create_time as ${prefix}create_time,
${alias}modify_user as ${prefix}modify_user,
${alias}modify_time as ${prefix}modify_time,
${alias}enable_flag as ${prefix}enabled_flag
</sql>
<!-- 根据功能操作ID查询功能操作详情(包括所属功能组、功能信息) -->
<select id="getFuncOperationVoById" resultMap="FuncOperationVoResultMap">
select
<!-- 使用include引用sql列定义,并设置对应alias、prefix参数 -->
<include refid="Operation_Base_Column_List">
<property name="alias" value="fo."/>
<property name="prefix" value=""/>
</include>
,
<!-- 使用include引用sql列定义,并设置对应alias、prefix参数 -->
<include refid="Func_Base_Column_List">
<property name="alias" value="f."/>
<property name="prefix" value="f_"/>
</include>
,
<!-- 使用include引用sql列定义,并设置对应alias、prefix参数 -->
<include refid="Group_Base_Column_List">
<property name="alias" value="fg."/>
<property name="prefix" value="fg_"/>
</include>
from system_func_operation fo
left join system_func f on f.id = fo.func_id and f.enable_flag = 0
left join system_func_group fg on fg.id = fo.func_group_id and fg.enable_flag = 0
<where>
fo.id = #{id}
and fo.enable_flag = 0
</where>
</select>
</mapper>
五、使用mapper.xml跨namespace的引用机制达成跨mapper.xml级别的复用
之前的整个重构过程为了方便讲解,所以都写在了同一个FuncOperationMapper.xml中,重构后的FuncOperationMapper.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.luo.demo.dao.FuncOperationMapper">
<!-- FuncOperation通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.luo.demo.entity.FuncOperation">
<id column="id" property="id" />
<result column="op_name" property="opName" />
<result column="op_code" property="opCode" />
<result column="func_group_id" property="funcGroupId" />
<result column="func_id" property="funcId" />
<result column="sort_num" property="sortNum" />
<result column="remarks" property="remarks" />
<result column="enabled" property="enabled" />
<result column="create_user" property="createUser" />
<result column="create_time" property="createTime" />
<result column="modify_user" property="modifyUser" />
<result column="modify_time" property="modifyTime" />
<result column="enable_flag" property="enableFlag" />
</resultMap>
<!-- FuncVo查询映射结果 -->
<resultMap id="FuncVoResultMap" type="com.luo.demo.vo.FuncVo">
<id column="id" property="id" />
<result column="func_name" property="funcName" />
<result column="func_code" property="funcCode" />
<result column="func_group_id" property="funcGroupId" />
<result column="entry_page_url" property="entryPageUrl" />
<result column="sort_num" property="sortNum" />
<result column="remarks" property="remarks" />
<result column="enabled" property="enabled" />
<result column="create_user" property="createUser" />
<result column="create_time" property="createTime" />
<result column="modify_user" property="modifyUser" />
<result column="modify_time" property="modifyTime" />
<result column="enable_flag" property="enableFlag" />
</resultMap>
<!-- FuncGroupVo查询映射结果 -->
<resultMap id="FuncGroupVoResultMap" type="com.luo.demo.vo.FuncGroupVo">
<id column="id" property="id" />
<result column="group_name" property="groupName" />
<result column="group_type" property="groupType" />
<result column="sort_num" property="sortNum" />
<result column="remarks" property="remarks" />
<result column="create_user" property="createUser" />
<result column="create_time" property="createTime" />
<result column="modify_user" property="modifyUser" />
<result column="modify_time" property="modifyTime" />
<result column="enable_flag" property="enableFlag" />
</resultMap>
<!-- FuncOperationVo映射结果 -->
<resultMap id="FuncOperationVoResultMap" type="com.luo.demo.vo.FuncOperationVo" extends="BaseResultMap">
<!-- 注意此处使用association.resultMap复用了原有的resultMap定义, -->
<!-- 同时使用association.columnPrefix来统一设置result.column的别名前缀 -->
<association property="func" columnPrefix="f_" resultMap="FuncVoResultMap"/>
<association property="funcGroup" columnPrefix="fg_" resultMap="FuncGroupVoResultMap"/>
</resultMap>
<!-- FuncOperation通用查询结果列 - 定义 表名前缀参数${alias}、列名前缀参数${prefix} -->
<sql id="Operation_Base_Column_List">
${alias}id as ${prefix}id,
${alias}op_name as ${prefix}op_name,
${alias}op_code as ${prefix}op_code,
${alias}sort_num as ${prefix}sort_num,
${alias}remarks as ${prefix}remarks,
${alias}enabled as ${prefix}enabled,
${alias}create_user as ${prefix}create_user,
${alias}create_time as ${prefix}create_time,
${alias}modify_user as ${prefix}modify_user,
${alias}modify_time as ${prefix}modify_time,
${alias}enable_flag as ${prefix}enable_flag
</sql>
<!-- Func通用查询结果列 - 定义 表名前缀参数${alias}、列名前缀参数${prefix} -->
<sql id="Func_Base_Column_List">
${alias}id as ${prefix}id,
${alias}func_name as ${prefix}func_name,
${alias}func_code as ${prefix}func_code,
${alias}entry_page_url as ${prefix}entry_page_url,
${alias}sort_num as ${prefix}sort_num,
${alias}remarks as ${prefix}remarks,
${alias}enabled as ${prefix}enabled,
${alias}create_user as ${prefix}create_user,
${alias}create_time as ${prefix}create_time,
${alias}modify_user as ${prefix}modify_user,
${alias}modify_time as ${prefix}modify_time,
${alias}enable_flag as ${prefix}enable_flag
</sql>
<!-- FuncGroup通用查询结果列 - 定义 表名前缀参数${alias}、列名前缀参数${prefix} -->
<sql id="Group_Base_Column_List">
${alias}id as ${prefix}id,
${alias}group_name as ${prefix}group_name,
${alias}group_type as ${prefix}group_type,
${alias}sort_num as ${prefix}sort_num,
${alias}remarks as ${prefix}remarks,
${alias}create_user as ${prefix}create_user,
${alias}create_time as ${prefix}create_time,
${alias}modify_user as ${prefix}modify_user,
${alias}modify_time as ${prefix}modify_time,
${alias}enable_flag as ${prefix}enabled_flag
</sql>
<!-- 根据功能操作ID查询功能操作详情(包括所属功能组、功能信息) -->
<select id="getFuncOperationVoById" resultMap="FuncOperationVoResultMap">
select
<!-- 使用include引用sql列定义,并设置对应alias、prefix参数 -->
<include refid="Operation_Base_Column_List">
<property name="alias" value="fo."/>
<property name="prefix" value=""/>
</include>
,
<!-- 使用include引用sql列定义,并设置对应alias、prefix参数 -->
<include refid="Func_Base_Column_List">
<property name="alias" value="f."/>
<property name="prefix" value="f_"/>
</include>
,
<!-- 使用include引用sql列定义,并设置对应alias、prefix参数 -->
<include refid="Group_Base_Column_List">
<property name="alias" value="fg."/>
<property name="prefix" value="fg_"/>
</include>
from system_func_operation fo
left join system_func f on f.id = fo.func_id and f.enable_flag = 0
left join system_func_group fg on fg.id = fo.func_group_id and fg.enable_flag = 0
<where>
fo.id = #{id}
and fo.enable_flag = 0
</where>
</select>
</mapper>
但是实际开发过程中,通常每个table都会对应单独的mapper.xml定义,例如本文中提到的3个table即分别对应3个mapper.xml定义:
table | mapper.xml |
---|---|
system_func_operation | FuncOperationMapper.xml |
system_func | FuncMapper.xml |
system_func_group | FuncGroupMapper.xml |
在开发初期,我们可以通过Mybatis代码生成器生成对应的entity、dao类及mapper.xml定义,而mapper.xml中通常可选择生成单表的Base_Column_List、BaseResultMap定义,而在不同的mapper.xml可通过namespace前缀跨mapper.xml复用sql、resultmap等定义,
例如FuncMapper.xml定义如下,注意其namespace为com.luo.demo.dao.FuncMapper
:
<?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.luo.demo.dao.FuncMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.luo.demo.entity.Func">
<result column="id" property="id" />
<result column="create_user" property="createUser" />
<result column="create_time" property="createTime" />
<result column="modify_user" property="modifyUser" />
<result column="modify_time" property="modifyTime" />
<result column="enable_flag" property="enableFlag" />
<result column="func_name" property="funcName" />
<result column="func_code" property="funcCode" />
<result column="func_group_id" property="funcGroupId" />
<result column="entry_page_url" property="entryPageUrl" />
<result column="sort_num" property="sortNum" />
<result column="remarks" property="remarks" />
<result column="enabled" property="enabled" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
create_user,
create_time,
modify_user,
modify_time,
enable_flag,
func_name, func_code, func_group_id, entry_page_url, sort_num, remarks, enabled
</sql>
</mapper>
则在其他mapper.xml可通过{namespace}.{sql.id | resultmap.id}
的形式跨mapper.xml复用sql定义,
例如如下FuncOperationMapper.xml中,
通过resultMap="com.luo.demo.dao.FuncMapper.BaseVoResultMap"
复用FuncMappers.xml中的resultMap定义,
通过<include refid="com.luo.demo.dao.FuncMapper.Base_Column_List"/>
复用FuncMappers.xml中的sql定义:
<?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.luo.demo.dao.FuncOperationMapper">
<resultMap id="FuncOperationVoResultMap" type="com.luo.demo.vo.FuncOperationVo" extends="BaseResultMap">
<!-- association.resulMap属性跨namespace引用FuncMappers.xml中的resultmap定义 -->
<association property="func" columnPrefix="f_" resultMap="com.luo.demo.dao.FuncMapper.BaseResultMap"/>
...
</resultMap>
<select id="getFuncOperationVoById" resultMap="FuncOperationVoResultMap">
select
<!-- include.refid属性跨namespace引用FuncMappers.xml中的sql定义-->
<include refid="com.luo.demo.dao.FuncMapper.Base_Column_List"/>
...
</select>
</mapper>
通过跨namespace的引用机制:
- 保证了每个mapper.xml尽量只对应单独table的相关sql定义
- 同时也方便了跨mapper.xml级别的复用,避免重复定义。
最终拆解后的3个mappers.xml定义如下:
FuncMapper.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.luo.demo.dao.FuncMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.luo.demo.entity.Func">
<id column="id" property="id" />
<result column="func_name" property="funcName" />
<result column="func_code" property="funcCode" />
<result column="func_group_id" property="funcGroupId" />
<result column="entry_page_url" property="entryPageUrl" />
<result column="sort_num" property="sortNum" />
<result column="remarks" property="remarks" />
<result column="enabled" property="enabled" />
<result column="create_user" property="createUser" />
<result column="create_time" property="createTime" />
<result column="modify_user" property="modifyUser" />
<result column="modify_time" property="modifyTime" />
<result column="enable_flag" property="enableFlag" />
</resultMap>
<!-- 通用Vo查询映射结果 -->
<resultMap id="BaseVoResultMap" type="com.luo.demo.vo.FuncVo" extends="BaseResultMap">
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
${alias}id as ${prefix}id,
${alias}func_name as ${prefix}func_name,
${alias}func_code as ${prefix}func_code,
${alias}entry_page_url as ${prefix}entry_page_url,
${alias}sort_num as ${prefix}sort_num,
${alias}remarks as ${prefix}remarks,
${alias}enabled as ${prefix}enabled,
${alias}create_user as ${prefix}create_user,
${alias}create_time as ${prefix}create_time,
${alias}modify_user as ${prefix}modify_user,
${alias}modify_time as ${prefix}modify_time,
${alias}enable_flag as ${prefix}enable_flag
</sql>
</mapper>
FuncGroupMapper.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.luo.demo.dao.FuncGroupMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.luo.demo.entity.FuncGroup">
<id column="id" property="id" />
<result column="group_name" property="groupName" />
<result column="group_type" property="groupType" />
<result column="sort_num" property="sortNum" />
<result column="remarks" property="remarks" />
<result column="create_user" property="createUser" />
<result column="create_time" property="createTime" />
<result column="modify_user" property="modifyUser" />
<result column="modify_time" property="modifyTime" />
<result column="enable_flag" property="enableFlag" />
</resultMap>
<!-- 通用Vo查询映射结果 -->
<resultMap id="BaseVoResultMap" type="com.luo.demo.vo.FuncGroupVo" extends="BaseResultMap">
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
${alias}id as ${prefix}id,
${alias}group_name as ${prefix}group_name,
${alias}group_type as ${prefix}group_type,
${alias}sort_num as ${prefix}sort_num,
${alias}remarks as ${prefix}remarks,
${alias}create_user as ${prefix}create_user,
${alias}create_time as ${prefix}create_time,
${alias}modify_user as ${prefix}modify_user,
${alias}modify_time as ${prefix}modify_time,
${alias}enable_flag as ${prefix}enabled_flag
</sql>
</mapper>
FuncOperationMapper.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.luo.demo.dao.FuncOperationMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.luo.demo.entity.FuncOperation">
<id column="id" property="id" />
<result column="op_name" property="opName" />
<result column="op_code" property="opCode" />
<result column="func_group_id" property="funcGroupId" />
<result column="func_id" property="funcId" />
<result column="sort_num" property="sortNum" />
<result column="remarks" property="remarks" />
<result column="enabled" property="enabled" />
<result column="create_user" property="createUser" />
<result column="create_time" property="createTime" />
<result column="modify_user" property="modifyUser" />
<result column="modify_time" property="modifyTime" />
<result column="enable_flag" property="enableFlag" />
</resultMap>
<!-- FuncOperationVo映射结果 -->
<resultMap id="FuncOperationVoResultMap" type="com.luo.demo.vo.FuncOperationVo" extends="BaseResultMap">
<association property="func" columnPrefix="f_" resultMap="com.luo.demo.dao.FuncMapper.BaseVoResultMap"/>
<association property="funcGroup" columnPrefix="fg_" resultMap="com.luo.demo.dao.FuncGroupMapper.BaseVoResultMap"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
${alias}id as ${prefix}id,
${alias}op_name as ${prefix}op_name,
${alias}op_code as ${prefix}op_code,
${alias}sort_num as ${prefix}sort_num,
${alias}remarks as ${prefix}remarks,
${alias}enabled as ${prefix}enabled,
${alias}create_user as ${prefix}create_user,
${alias}create_time as ${prefix}create_time,
${alias}modify_user as ${prefix}modify_user,
${alias}modify_time as ${prefix}modify_time,
${alias}enable_flag as ${prefix}enable_flag
</sql>
<!-- 根据功能操作ID查询功能操作详情(包括所属功能组、功能信息) -->
<select id="getFuncOperationVoById" resultMap="FuncOperationVoResultMap">
select
<include refid="Base_Column_List">
<property name="alias" value="fo."/>
<property name="prefix" value=""/>
</include>
,
<include refid="com.luo.demo.dao.FuncMapper.Base_Column_List">
<property name="alias" value="f."/>
<property name="prefix" value="f_"/>
</include>
,
<include refid="com.luo.demo.dao.FuncGroupMapper.Base_Column_List">
<property name="alias" value="fg."/>
<property name="prefix" value="fg_"/>
</include>
from system_func_operation fo
left join system_func f on f.id = fo.func_id and f.enable_flag = 0
left join system_func_group fg on fg.id = fo.func_group_id and fg.enable_flag = 0
<where>
fo.id = #{id}
and fo.enable_flag = 0
</where>
</select>
</mapper>
搞定,收工!
参考:
https://mybatis.org/mybatis-3/sqlmap-xml.html#sql
https://groups.google.com/g/mybatis-user/c/zQdMXwKoJwU/m/UJvPbDoRBQAJ
https://blog.csdn.net/weixin_45645403/article/details/113061133