长沙长沙网站建设,微信公众号的小程序怎么开发,wordpress几十万篇文章,网站建设维护合同范本# 使用collection标签需求#xff1a;根据用户id查询用户信息的同时获取用户拥有的角色#xff0c;一个用户可以拥有1个或多个角色。一般情况下#xff0c;不建议直接修改数据库表对应的实体类。所以这里我们延用之前博客中新建的类SysUserExtend#xff0c;并添加如下代码… # 使用collection标签需求根据用户id查询用户信息的同时获取用户拥有的角色一个用户可以拥有1个或多个角色。一般情况下不建议直接修改数据库表对应的实体类。所以这里我们延用之前博客中新建的类SysUserExtend并添加如下代码如下所示/** * 用户的角色集合 */private List sysRoleList;public ListgetSysRoleList() { return sysRoleList;}public void setSysRoleList(List sysRoleList) { this.sysRoleList sysRoleList;}然后我们在接口SysUserMapper中添加如下方法/** * 获取所有的用户以及对应的所有角色 * * return */List selectAllUserAndRoles();接着在对应的SysUserMapper.xml中添加如下代码resultMap iduserRoleListMap typecom.zwwhnly.mybatisaction.model.SysUserExtend extendssysUserMap collection propertysysRoleList columnPrefixrole_ ofTypecom.zwwhnly.mybatisaction.model.SysRole id propertyid columnid/ result propertyroleName columnrole_name/ result propertyenabled columnenabled/ result propertycreateBy columncreate_by/ result propertycreateTime columncreate_time jdbcTypeTIMESTAMP/ collectionresultMap因为我们在前面的博客中已经建过角色表的roleMapresultMap idroleMap typecom.zwwhnly.mybatisaction.model.SysRole id propertyid columnid/ result propertyroleName columnrole_name/ result propertyenabled columnenabled/ result propertycreateBy columncreate_by/ result propertycreateTime columncreate_time jdbcTypeTIMESTAMP/resultMap所以上面的collection标签可以简化为collection propertysysRoleList columnPrefixrole_ resultMapcom.zwwhnly.mybatisaction.mapper.SysRoleMapper.roleMapcollection新建接口对应的查询代码使用上面新建的userRoleListMap如下所示 SELECT u.id, u.user_name, u.user_password, u.user_email, 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最后在SysUserMapperTest测试类中添加如下测试方法Testpublic void testSelectAllUserAndRoles() { SqlSession sqlSession getSqlSession(); try { SysUserMapper sysUserMapper sqlSession.getMapper(SysUserMapper.class); List sysUserList sysUserMapper.selectAllUserAndRoles(); System.out.println(用户数 sysUserList.size()); for (SysUserExtend sysUser : sysUserList) { System.out.println(用户名 sysUser.getUserName()); for (SysRole sysRole : sysUser.getSysRoleList()) { System.out.println(角色名 sysRole.getRoleName()); } } } finally { sqlSession.close(); }}运行测试代码测试通过输出日志如下DEBUG [main] - Preparing: SELECT u.id, u.user_name, u.user_password, u.user_email, 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.idDEBUG [main] - Parameters:TRACE [main] - Columns: id, user_name, user_password, user_email, create_time, role_id, role_role_name, role_enabled, role_create_by, role_create_timeTRACE [main] - Row: 1, admin, 123456, adminmybatis.tk, 2019-06-27 18:21:07.0, 1, 管理员, 1, 1, 2019-06-27 18:21:12.0TRACE [main] - Row: 1, admin, 123456, adminmybatis.tk, 2019-06-27 18:21:07.0, 2, 普通用户, 1, 1, 2019-06-27 18:21:12.0TRACE [main] - Row: 1001, test, 123456, testmybatis.tk, 2019-06-27 18:21:07.0, 2, 普通用户, 1, 1, 2019-06-27 18:21:12.0DEBUG [main] - Total: 3用户数2用户名admin角色名管理员角色名普通用户用户名test角色名普通用户# MyBatis合并规则观察上面的日志我们的Sql语句查询到了3条数据在数据库查询的话也是返回如下的数据但经过MyBatis配置的映射到最后合并为了2个用户其中第1个用户包含了2个角色第2个用户包含了1个角色那么MyBatis是根据什么规则合并的呢MyBatis在处理结果的时候会判断结果是否相同如果是相同的结果则只会保留第一个结果所以关键点就是MyBatis如何判断结果是否相同。判断结果是否相同时最简单的情况就是在映射配置中至少有1个id标签上面使用的sysUserMap就配置了id标签id propertyid columnid/一般情况下id标签配置的字段为表的主键如果是联合主键可以配置多个id标签。id标签的作用就是在嵌套的映射配置时判断数据是否相同当配置id标签时MyBatis只需要逐条比较所有数据中id标签配置的字段值是否相同即可。也可以不配置id标签将上面的代码修改为result propertyid columnid/使用result不会影响查询结果但是此时MyBatis就要对所有字段进行比较因此当字段数为M时如果查询结果有N条就需要比较M*N次如果配置了id标签只需要比较N次即可所以要尽可能的配置id标签。结合上面的例子因为Sql的查询结果中前2条数据中用户的id是相同的所以会合并为1个用户所以最终的结果是2个用户。为了更清楚的理解id标签的作用我们将sysUserMap临时修改为resultMap idsysUserMap typecom.zwwhnly.mybatisaction.model.SysUser id propertyuserPassword columnuser_password/ result propertyid columnid/ result propertyuserName columnuser_name/ result propertyuserEmail columnuser_email/ result propertyuserInfo columnuser_info/ result propertyheadImg columnhead_img jdbcTypeBLOB/ result propertycreateTime columncreate_time jdbcTypeTIMESTAMP/resultMap运行测试方法输出的部分日志如下用户数1用户名admin角色名管理员角色名普通用户因为3个用户的密码都是123456所以查询到的3条数据只保留了第一个用户admin包含了2个角色。有的同学也许会问为什么不是拥有3个角色呢这是因为MyBatis会对嵌套查询的每一级对象都进行属性比较MyBatis会先比较顶层的对象如果SysUser部分相同就继续比较SysRole部分如果SysRole不同就会增加一个SysRole如果相同就保留前一个。如果SysRole还有下一级依次按照规则去比较。上面的“普通用户”角色重复了所以只保留了前1个导致最终的结果中只包含2个角色而不是3个。# 源码及参考源码地址https://github.com/zwwhnly/mybatis-action.git欢迎下载。刘增辉《MyBatis从入门到精通》作者申城异乡人来源https://www.cnblogs.com/zwwhnly/p/11194028.html 往期推荐 ?Github移动端IDEA 2019.3.4JDK 14都发布了赶快尝鲜MyBatis中如何使用association标签实现嵌套查询有点惨百度工程师挖矿4 个月控制 155 台服务器挖矿获利 10万被判 3 年 点击