mybatis高级映射之一对多映射 collection 集合的嵌套查询 一个用户对应多个角色,每个角色对应多个权限
collection 集合的嵌套查询通过自下而上的过程来实这样一个两层嵌套的功能,并且这个自下而上的过程中的每一个方法都是一个独立可用的方法,最后的结果都是以前一个方法为基础的,所有对象设置为延迟加载,因此每个方法都可以单独作为一个普通(没有嵌套)的查询存在。
1. privilegeMapper.xml中添加内容:
<resultMap id="privilegeMap" type="com.example.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中:
<resultMap id="rolePrivilegeListMapSelect" extends="roleMap" type="com.example.simple.model.SysRole"> <collection property="privilegeList" fetchType="lazy" column="{roleId = id}" select="com.example.simple.mapper.PrivilegeMapper.selectPrivilegeByRoleId"/> </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>
3. userMapper.xml中:
<resultMap id="userRoleListMapSelect" extends="userMap" type="com.example.simple.model.SysUser"> <collection property="roleList" fetchType="lazy" column="{userId = id}" select="com.example.simple.mapper.RoleMapper.selectRoleByUserId"/> </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. 接口如下:
/* * 通过嵌套查询获取指定用户的信息以及用户的角 色和权限信息 * */ SysUser selectAllUserAndRolesSelect(Long id);
5. 测试如下:
@Test public void testSelectAllUserAndRolesSelect(){ SqlSession sqlSession = getSqlSession(); try{ UserMapper userMapper = sqlSession.getMapper(UserMapper.class); SysUser user = userMapper.selectAllUserAndRolesSelect(1L); System.out.println("用户名:" + user.getUserName()); for(SysRole role : user.getRoleList() ){ System.out.println("角色名:" + role.getRoleName()); for(SysPrivilege privilege : role.getPrivilegeList()){ System.out.println("权限:"+ privilege.getPrivilegeName()); } } }finally { sqlSession.close(); } }
测试结果如下:
简单分析这段日志,当执行selectAllUserAndRolesSelect 方法后,可以得到 admin用户的信息,由于延迟加载,此时还不知道该用户有几个角色。当调用 user.getRoleList()方法进行遍历时 MyBati 执行了第一层的嵌套查询,查询出了该用户的两个角色。对这两个角色进行遍历获取角色对应的权限信息,因为己经有两个角色,所以分别对两个角色进行遍历时会查询两次角色的权限信息。特别需要注意的是 之所以可以根据需要查询数据,除了和fetchType 有关,还和全局的 aggressiveLazyLoading 属性有关,这个属性在介绍association 时被配置成了 false ,所以才会起到按需加载的作用通过自下而上的方式学习这种映射结果的配置 大家应该对 collection 的用法有了一定的了解,熟练掌握 assoc iation collection 的配置,在某些情况下会带给我们很大的便利。
aggressiveLazyLoading 在mybatis_config.xml中进行设置:
<setting name="aggressiveLazyLoading" value="false"/>