【笔记】Mybatis高级查询(四)--使用resultMap的标签实现一对多和多对多查询

【笔记】Mybatis高级查询(准备)
【笔记】Mybatis高级查询(一)–使用自动映射处理一对一关系
【笔记】Mybatis高级查询(二)–使用resultMap配置一对一映射
【笔记】Mybatis高级查询(三)–使用标签实现嵌套查询及延迟加载
【笔记】Mybatis高级查询(五)–使用resultMap的进行嵌套查询及延迟加载
【笔记】Mybatis高级查询(小结)–嵌套查询及延迟加载
【笔记】Mybatis高级查询(六)–鉴别器discrimiator的使用
【笔记】Mybatis高级查询(七)–存储过程调用
【笔记】Mybatis高级查询(八)–枚举处理器的使用
【笔记】Mybatis高级查询(九)–Mybatis代码生成器的使用
【笔记】Mybatis高级查询(十)–Mybatis缓存使用

集合的嵌套结果映射就是指通过一次SQL查询将所有的结果查询出来,然后映射到不同的对象中。在一对多的关系中,主表一条数据会对应关联表的多条数据。因此一般查询时会查询出多条结果,按照一对多的数据映射时,最终的结果数会小于等于查询的总记录数。

在RBAC权限系统中一个用户拥有多个角色,一个角色又拥有多个权限。以下例子通过嵌套查询查出某个用户及用户角色。当输入用户编号时为一对多查询,不输入编号时为多对多查询。

1. 在SysUser中加入roles属性,如下:

	/**
     * 用户的角色集合(一个用户可以有多个角色)
     */
    private List roles;

	public List getRoles() {
		return roles;
	}

	public void setRoles(List roles) {
		this.roles = roles;
	}

2. 在SysUserMapper.xml中加入resultMap和selectRolesById,如下:

  
  
    
    
    
  
  
  
  

3. 在SysUserMapper接口中加入selectRolesById方法,如下:

	/**
     * 使用resultMap的标签进行一对多查询
     * @param id
     * @return
     */
    List selectRolesById(@Param("id") Long id);

4. 在UserMaperTest中加入selectRolesById测试方法,如下:

	@Test
	public void testSelectRolesById() {
		// 获取SqlSession
		SqlSession sqlSession = openSession();
		try {
			// 获取SysUserMapper接口
			SysUserMapper userMapper = sqlSession.getMapper(SysUserMapper.class);
			
			// 调用selectRolesById方法
			List users = userMapper.selectRolesById(1L);
			
			System.out.println("用户数:" + users.size());
			for (SysUser user : users) {
				System.out.println("用户:" + user);
				for (SysRole role : user.getRoles()) {
					System.out.println("--角色:" + role);
				}
				System.out.println();
			}
			
			System.out.println();
		} finally {
			sqlSession.close();
		}
	}

5. 测试结果(id=1L时,为一对多查询)

[ex.mybatis.rbac.mapper.SysUserMapper.selectRolesById] - ==>  Preparing: select u.id, u.user_name, u.user_password, u.user_email, u.create_time, u.user_info, u.head_img, r.id r_id, r.role_name r_role_name, r.enabled r_enabled, r.create_by r_create_by, r.create_time r_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 where u.id = ? 
[ex.mybatis.rbac.mapper.SysUserMapper.selectRolesById] - ==> Parameters: 1(Long)
[ex.mybatis.rbac.mapper.SysUserMapper.selectRolesById] - <==    Columns: id, user_name, user_password, user_email, create_time, user_info, head_img, r_id, r_role_name, r_enabled, r_create_by, r_create_time
[ex.mybatis.rbac.mapper.SysUserMapper.selectRolesById] - <==        Row: 1, admin, 123456, [email protected], 2018-10-01 18:27:36.0, <>, <>, 1, 管理员, 1, 1, 2018-10-01 18:27:36.0
[ex.mybatis.rbac.mapper.SysUserMapper.selectRolesById] - <==        Row: 1, admin, 123456, [email protected], 2018-10-01 18:27:36.0, <>, <>, 2, 普通用户, 0, 1, 2018-10-01 18:27:37.0
[ex.mybatis.rbac.mapper.SysUserMapper.selectRolesById] - <==      Total: 2

用户:SysUser [id=1, userName=admin, userPassword=123456, [email protected], createTime=Mon Oct 01 18:27:36 CST 2018, userInfo=管理员, headImg=null]
--角色:SysRole [id=1, roleName=管理员, enabled=enabled, createBy=1, createTime=Mon Oct 01 18:27:36 CST 2018]
--角色:SysRole [id=2, roleName=普通用户, enabled=disabled, createBy=1, createTime=Mon Oct 01 18:27:37 CST 2018]

6. 测试结果(id=null时,为多对多查询)

[ex.mybatis.rbac.mapper.SysUserMapper.selectRolesById] - ==>  Preparing: select u.id, u.user_name, u.user_password, u.user_email, u.create_time, u.user_info, u.head_img, r.id r_id, r.role_name r_role_name, r.enabled r_enabled, r.create_by r_create_by, r.create_time r_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 
[ex.mybatis.rbac.mapper.SysUserMapper.selectRolesById] - ==> Parameters: 
[ex.mybatis.rbac.mapper.SysUserMapper.selectRolesById] - <==    Columns: id, user_name, user_password, user_email, create_time, user_info, head_img, r_id, r_role_name, r_enabled, r_create_by, r_create_time
[ex.mybatis.rbac.mapper.SysUserMapper.selectRolesById] - <==        Row: 1, admin, 123456, [email protected], 2018-10-01 18:27:36.0, <>, <>, 1, 管理员, 1, 1, 2018-10-01 18:27:36.0
[ex.mybatis.rbac.mapper.SysUserMapper.selectRolesById] - <==        Row: 1, admin, 123456, [email protected], 2018-10-01 18:27:36.0, <>, <>, 2, 普通用户, 0, 1, 2018-10-01 18:27:37.0
[ex.mybatis.rbac.mapper.SysUserMapper.selectRolesById] - <==        Row: 1001, test, 123456, [email protected], 2018-10-02 17:17:11.0, <>, <>, 2, 普通用户, 0, 1, 2018-10-01 18:27:37.0
[ex.mybatis.rbac.mapper.SysUserMapper.selectRolesById] - <==      Total: 3
用户数:2
用户:SysUser [id=1, userName=admin, userPassword=123456, [email protected], createTime=Mon Oct 01 18:27:36 CST 2018, userInfo=管理员, headImg=null]
--角色:SysRole [id=1, roleName=管理员, enabled=enabled, createBy=1, createTime=Mon Oct 01 18:27:36 CST 2018]
--角色:SysRole [id=2, roleName=普通用户, enabled=disabled, createBy=1, createTime=Mon Oct 01 18:27:37 CST 2018]

用户:SysUser [id=1001, userName=test, userPassword=123456, [email protected], createTime=Tue Oct 02 17:17:11 CST 2018, userInfo=测试用户, headImg=null]
--角色:SysRole [id=2, roleName=普通用户, enabled=disabled, createBy=1, createTime=Mon Oct 01 18:27:37 CST 2018]

通过日志可以看到,SQL执行的结果数为3条,后面输入的用户数为2,为什么呢?这是Mybatis对结果集进行了合并。

7. Mybatis结果集合并原理

  • Mybatis在处理结果集时,首先会根据resultMap中配置的属性判断结果是否相同,属性相当于表记录的主键,如果相同则认为是相同的记录则合并。如果resultMap没有配置属性,则会把resultMap中配置的所有字段进行比较,如果所有字段都相同则合并。只要有一个不相同都不合并。
  • 因此建议所有resultMap都配置属性以提高查询效率。

你可能感兴趣的:(mybatis)