记一次Mybatis mapper.xml中sql定义重构(resultMap.extends、columnPrefix、sql自定义参数、跨namespace复用)

一、引言

最近重构了一次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

猜你喜欢

转载自blog.csdn.net/luo15242208310/article/details/131192314