用戶,角色,資源,聯(lián)合查詢(使用xml)

向xml低頭,沒錯,我向xml低頭了。
前文:
用戶,角色,資源,聯(lián)合查詢(使用注解SQL)

注解sql的那種provider的文件格式,可能真的不是mybatis主推的模式,場景欠缺的很多,而當(dāng)你硬把改場景用這種方式實現(xiàn)時,反倒不優(yōu)雅了。還是回歸傳統(tǒng)吧,或許這就是xml這么多年屹立不倒的秘訣。

開始開始。

一段時間不見,gemini的表結(jié)構(gòu)被我改了改,結(jié)合各種方面優(yōu)化考慮,現(xiàn)在的他們是這樣的。
用戶表:

CREATE TABLE `g_user` (
  `id` int(32) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
  `user_id` bigint(32) NOT NULL COMMENT '用戶編號(業(yè)務(wù)id)',
  `identity_code` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '賬號',
  `nick_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '昵稱',
  `phone` varchar(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '聯(lián)系方式',
  `email` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '郵箱',
  `password` varchar(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '密碼',
  `lock` tinyint(1) DEFAULT '0' COMMENT '是否鎖定',
  `create_user_id` bigint(32) DEFAULT NULL COMMENT '創(chuàng)建人id',
  `update_user_id` bigint(32) DEFAULT NULL COMMENT '更新人id',
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  `rev` tinyint(8) DEFAULT '1' COMMENT '版本號',
  `delete_flag` tinyint(1) DEFAULT '0' COMMENT '刪除標(biāo)記',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

角色表:

CREATE TABLE `g_role` (
  `id` int(32) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
  `role_id` bigint(32) NOT NULL COMMENT '角色id',
  `role_code` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '角色編碼',
  `role_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '角色名稱',
  `create_user_id` bigint(32) DEFAULT NULL COMMENT '創(chuàng)建人id',
  `update_user_id` bigint(32) DEFAULT NULL COMMENT '更新人id',
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  `rev` tinyint(8) DEFAULT '1' COMMENT '版本號',
  `delete_flag` tinyint(1) DEFAULT '0' COMMENT '刪除標(biāo)記',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

用戶角色表:

CREATE TABLE `g_user_role` (
  `id` int(32) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
  `role_id` bigint(32) NOT NULL COMMENT '角色編碼',
  `user_id` bigint(32) NOT NULL COMMENT '用戶編碼',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

資源表:

CREATE TABLE `g_resource` (
  `id` int(32) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
  `resource_id` bigint(32) NOT NULL COMMENT '資源id',
  `resource_code` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '資源編碼',
  `resource_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '資源名稱',
  `create_user_id` int(32) DEFAULT NULL COMMENT '創(chuàng)建人id',
  `update_user_id` int(32) DEFAULT NULL COMMENT '更新人id',
  `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  `rev` tinyint(8) DEFAULT '1' COMMENT '版本號',
  `delete_flag` tinyint(1) DEFAULT '0' COMMENT '刪除標(biāo)記',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

角色資源表:

CREATE TABLE `g_res_role` (
  `id` int(32) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
  `role_id` bigint(32) NOT NULL COMMENT '角色id',
  `resource_id` bigint(32) NOT NULL COMMENT '資源id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

總體模式同過去沒有區(qū)別,只是加了一些字段,改了一些名字,變化了一些規(guī)則。
首先,過去我的表主鍵都是自增id,但我在映射關(guān)系中,也是使用的自增id,其實是不科學(xué)的。過去也不是沒想到給它一個主鍵自增id,一個業(yè)務(wù)id,一個編碼,一個名字。所有的業(yè)務(wù)表都這么設(shè)計的模式。只是覺得有必要嗎?但是實際的項目探索之后,其實還是很有必要的。粒度越細(xì),其實可變化性就越多,分工也越明確。只是略有復(fù)雜需要處理,具體還是看個人和項目吧??傊腋某闪爽F(xiàn)在的這樣。

開始切入正題。

我們現(xiàn)在需求的返回格式同過去一般無二。
1、用戶信息中帶角色列表,角色列表中再帶資源列表。
2、用戶信息中直接帶角色列表與資源列表。

對于vo文件我也沒有怎么改動。除了字段更名和添加字段以外,格式,模式,基本同過去一致。

主要看xml。
其實本質(zhì)是類似的。還是使用resultMap進行調(diào)控。
只是在注解sql中,用的是many=@Many()這樣的格式,在這里使用的就是collection標(biāo)簽。需要注意的是,所有的關(guān)聯(lián)字段(column)都必須顯式地被寫出來,也就是不能依賴通配符(*)的查詢結(jié)果。

直接貼圖吧。

資源持久化類
ResourceMapper.java:

public interface ResourceMapper {

    /**
     * 根據(jù)roleId獲取資源信息
     */

    List<ResourceVo> selectByRoleId(Long roleId);
}

ResourceMapper.xml
很簡單,只是普通的根據(jù)角色資源映射表查詢資源信息。

<?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.hekiraku.gemini.mapper.ResourceMapper">
    <resultMap id="resourceInfo" type="com.hekiraku.gemini.domain.vo.ResourceVo">
    </resultMap>
    <select id="selectByRoleId" resultMap="resourceInfo">
        select gr.*
        from g_resource gr
        left join g_res_role grr on gr.resource_id = grr.resource_id
        where grr.role_id = #{roleId}
    </select>
</mapper>

接下來看角色
角色持久化類
RoleMapper.java

public interface RoleMapper {
/**根據(jù)userId獲取所有角色信息*/
    List<RoleVo> selectByUserId(Long userId);
}

RoleMapper.xml
<注意:這里的關(guān)聯(lián)字段是role_id,因此在下面的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.hekiraku.gemini.mapper.RoleMapper">
    <resultMap id="roleInfo" type="com.hekiraku.gemini.domain.vo.RoleVo">
        <collection property="resources" column="role_id" javaType="java.util.List" select="com.hekiraku.gemini.mapper.ResourceMapper.selectByRoleId"/>
    </resultMap>
    <!--根據(jù)userId獲取相關(guān)角色信息-->
    <select id="selectByUserId" resultMap="roleInfo">
        select gr.*,grr.role_id as roleId
        from g_role gr
        left join g_user_role grr on gr.role_id = grr.role_id
        where grr.user_id = #{userId}
    </select>
</mapper>

用戶映射類
userMapper.java:

public interface UserMapper {
/**根據(jù)身份編碼獲取所有信息*/
    UserInfoVo selectByIdentityCode(String identityCode);
}

userMapper.xml:
<注意:這里的關(guān)聯(lián)字段是user_id,因此在下面的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.hekiraku.gemini.mapper.UserMapper">

    <resultMap id="userInfo" type="com.hekiraku.gemini.domain.vo.UserInfoVo">
        <collection property="roles" column="user_id" ofType="com.hekiraku.gemini.domain.vo.RoleVo" javaType="java.util.List" select="com.hekiraku.gemini.mapper.RoleMapper.selectByUserId"/>
    </resultMap>
    <select id="selectByIdentityCode" resultMap="userInfo">
        select gu.user_id as userId,gu.*
        from g_user gu
        where gu.identity_code = #{identityCode}
    </select>
</mapper>

關(guān)聯(lián)字段是什么呢?就是兩個sql關(guān)聯(lián)在一起的那個共同的字段。所以在寫關(guān)聯(lián)查詢的時候,一定一定要注意的事,關(guān)聯(lián)字段一定要作為B的條件。

結(jié)果集

end

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容