企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] ***** # 6.1.2 一对多映射 **推荐使用一对多的嵌套查询映射,不要使用嵌套结果** ## 6.1.2.1 collection集合的嵌套结果映射 一个系统用户拥有多个系统角色 **1 在SysUser.java中增加** ``` package tk.mybatis.simple.model; import java.io.Serializable; import java.util.Date; import java.util.List; /** * 用户表 */ public class SysUser implements Serializable { private static final long serialVersionUID = -328602757171077630L; /** * 用户的角色集合 */ private List<SysRole> roleList; public List<SysRole> getRoleList() { return roleList; } public void setRoleList(List<SysRole> roleList) { this.roleList = roleList; } } ``` **2 在UserMapper.xml中** ``` <resultMap id="userRoleListMap" extends="userMap" type="tk.mybatis.simple.model.SysUser"> <collection property="roleList" columnPrefix="role_" resultMap="tk.mybatis.simple.mapper.RoleMapper.roleMap"/> </resultMap> ``` **3 在UserMapper.xml中** 查询所有用户及其对应的角色 ``` <select id="selectAllUserAndRoles" resultMap="userRoleListMap"> select u.id, u.user_name, u.user_password, u.user_email, u.user_info, u.head_img, u.create_time, r.id role_id, r.role_name role_role_name, r.enabled role_enabled, r.create_by role_create_by, r.create_time role_create_time from sys_user u inner join sys_user_role ur on u.id = ur.user_id inner join sys_role r on ur.role_id = r.id </select> ``` **4 在UserMapper接口中增加如下的对应方法** ``` * 获取所有的用户以及对应的所有角色 * * @return */ List<SysUser> selectAllUserAndRoles(); ``` MyBatis 在处理结果的时候, 会判断结果是否相同, 如果是相同的 结果, 则只会保留第一个结果, 所以这个问题的关键点就是 MyBatis 如 何判断结果是否相同。 MyBatis 判断结果是否相同时, 最简单的情况就 是在映射配置中至少有一个id标签, 在userMap中配置如下。 **<id property="id" column="id"/>** 我们对 id(构造方法中为 idArg) 的理解一般是, 它配置的字段为 表的主键(联合主键时可以配置多个id标签) , 因为MyBatis的 resultMap只用于配置结果如何映射, 并不知道这个表具体如何。 id的唯 一作用就是在嵌套的映射配置时判断数据是否相同, 当配置id标签时, MyBatis只需要逐条比较所有数据中id标签配置的字段值是否相同即 可。 在配置嵌套结果查询时, 配置id标签可以提高处理效率。 这样一来, 上面的查询就不难理解了。 因为前两条数据的userMap 部分的id相同, 所以它们属于同一个用户, 因此这条数据会合并到同一 个用户中 ## 6.1.2.2 collection集合的嵌套查询 示例 : 通过角色id获取该角色对应的所有权限信息 **1 在PrivilegeMapper.xml中添加如下方法** 通过角色id获取该角色对应的所有权限信息 ``` <resultMap id="privilegeMap" type="tk.mybatis.simple.model.SysPrivilege"> <id property="id" column="id"/> <result property="privilegeName" column="privilege_name"/> <result property="privilegeUrl" column="privilege_url"/> </resultMap> <select id="selectPrivilegeByRoleId" resultMap="privilegeMap"> select p.* from sys_privilege p inner join sys_role_privilege rp on rp.privilege_id = p.id where role_id = #{roleId} </select> ``` **2 在RoleMapper.xml中配置映射和对应的查询方法** 通过系统用户id查询该用户对应的所有系统角色 ``` <resultMap id="rolePrivilegeListMapSelect" extends="roleMap" type="tk.mybatis.simple.model.SysRole"> <collection property="privilegeList" fetchType="lazy" select="tk.mybatis.simple.mapper.PrivilegeMapper.selectPrivilegeByRoleId" column="{roleId=id}"/> </resultMap> <select id="selectRoleByUserId" resultMap="rolePrivilegeListMapSelect"> select r.id, r.role_name, r.enabled, r.create_by, r.create_time from sys_role r inner join sys_user_role ur on ur.role_id = r.id where ur.user_id = #{userId} </select> ``` 在上面代码中要注意column属性配置的{roleId=id}, roleId 是select 指定方法selectPrivilegeByRoleId查询中的参数, id是当前查询 selectRoleByUserId中查询出的角色 id。 **3 在UserMapper.xml中添加如下映射和查询** 通过系统用户id查出对应系统用户和所有角色 ``` <resultMap id="userRoleListMapSelect" extends="userMap" type="tk.mybatis.simple.model.SysUser"> <collection property="roleList" fetchType="lazy" select="tk.mybatis.simple.mapper.RoleMapper.selectRoleByUserId" column="{userId=id}"/> </resultMap> <select id="selectAllUserAndRolesSelect" resultMap="userRoleListMapSelect"> select u.id, u.user_name, u.user_password, u.user_email, u.user_info, u.head_img, u.create_time from sys_user u where u.id = #{id} </select> ``` **4 在UserMapper.xml中增加方法** 通过嵌套查询获取指定用户的信息,以及用户的角色和权限信息 ``` SysUser selectAllUserAndRolesSelect(Long id); ```