This blog mainly on the use of collection tags implement nested queries.
1. Demand Upgrade
In the blog post, we realized the demand: the user has acquired the role based user queries while the user id information.
Because the role can have multiple permissions, so this blog we upgrade requirements: obtaining permission roles include roles and owned by the user based on the user id to query the user information at the same time.
2. implementation
Because we need to use the mapping table permission, so we need to add the following mapping SysPrivilegeMapper.xml in:
<resultMap id="sysPrivilegeMap" type="com.zwwhnly.mybatisaction.model.SysPrivilege">
<id property="id" column="id"/>
<result property="privilegeName" column="privilege_name"/>
<result property="privilegeUrl" column="privilege_url"/>
</resultMap>
Not propose to amend the database entity class corresponding to the table under normal circumstances, so here we create a new class SysRoleExtend, it inherited SysRole class, and add the following fields:
package com.zwwhnly.mybatisaction.model;
import java.util.List;
public class SysRoleExtend extends SysRole {
/**
* 角色包含的权限列表
*/
private List<SysPrivilege> sysPrivilegeList;
public List<SysPrivilege> getSysPrivilegeList() {
return sysPrivilegeList;
}
public void setSysPrivilegeList(List<SysPrivilege> sysPrivilegeList) {
this.sysPrivilegeList = sysPrivilegeList;
}
}
Then the new mapping SysRoleMapper.xml the following:
<resultMap id="rolePrivilegeListMap" extends="roleMap"
type="com.zwwhnly.mybatisaction.model.SysRoleExtend">
<collection property="sysPrivilegeList" columnPrefix="privilege_"
resultMap="com.zwwhnly.mybatisaction.mapper.SysPrivilegeMapper.sysPrivilegeMap"/>
</resultMap>
roleMap here in our previous blog has been defined, as follows:
<resultMap id="roleMap" type="com.zwwhnly.mybatisaction.model.SysRole">
<id property="id" column="id"/>
<result property="roleName" column="role_name"/>
<result property="enabled" column="enabled"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
</resultMap>
com.zwwhnly.mybatisaction.mapper.SysPrivilegeMapper.sysPrivilegeMap
Is our newly erected in SysPrivilegeMapper.xml mapping sysPrivilegeMap.
Then, on the blog post in userRoleListMap you need to be amended as follows:
<resultMap id="userRoleListMap" type="com.zwwhnly.mybatisaction.model.SysUserExtend" extends="sysUserMap">
<collection property="sysRoleList" columnPrefix="role_"
resultMap="com.zwwhnly.mybatisaction.mapper.SysRoleMapper.rolePrivilegeListMap">
</collection>
</resultMap>
And to amend Part blog, select the id tag codes selectAllUserAndRoles, because to be associated roles and permissions table permissions table:
<select id="selectAllUserAndRoles" resultMap="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,
p.id role_privilege_id,
p.privilege_name role_privilege_privilege_name,
p.privilege_url role_privilege_privilege_url
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
INNER JOIN sys_role_privilege rp ON rp.role_id = r.id
INNER JOIN sys_privilege p ON p.id = rp.privilege_id
</select>
Precautions:
Alias column name here sys_privilege table prefix role_privilege_
because userRoleListMap in the collection of columnPrefix property role_
, and specified com.zwwhnly.mybatisaction.mapper.SysRoleMapper.rolePrivilegeListMap
in the collection of columnPrefix property privilege_
, so here is a prefix required overlay, it becomes role_privilege_
.
3. Unit Testing
Modify the test methods in Part blog built testSelectAllUserAndRoles () code:
@Test
public void testSelectAllUserAndRoles() {
SqlSession sqlSession = getSqlSession();
try {
SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);
List<SysUserExtend> sysUserList = sysUserMapper.selectAllUserAndRoles();
System.out.println("用户数:" + sysUserList.size());
for (SysUserExtend sysUser : sysUserList) {
System.out.println("用户名:" + sysUser.getUserName());
for (SysRoleExtend sysRoleExtend : sysUser.getSysRoleList()) {
System.out.println("角色名:" + sysRoleExtend.getRoleName());
for (SysPrivilege sysPrivilege : sysRoleExtend.getSysPrivilegeList()) {
System.out.println("权限名:" + sysPrivilege.getPrivilegeName());
}
}
}
} finally {
sqlSession.close();
}
}
Run the test code, the test passes, outputting the log follows:
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, p.id role_privilege_id, p.privilege_name role_privilege_privilege_name, p.privilege_url role_privilege_privilege_url 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 INNER JOIN sys_role_privilege rp ON rp.role_id = r.id INNER JOIN sys_privilege p ON p.id = rp.privilege_id
DEBUG [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_time, role_privilege_id, role_privilege_privilege_name, role_privilege_privilege_url
TRACE [main] - <== Row: 1, admin, 123456, [email protected], 2019-06-27 18: 21: 07.0, 1, administrators, 1, 1, 2019-06-27 18:21 : 12.0, 1, user management, / users
TRACE [main] - <== Row: 1, admin, 123456, [email protected], 2019-06-27 18: 21: 07.0, 1, administrators, 1, 1, 2019-06-27 18:21 : 12.0, 2, role management, / roles
TRACE [main] - <== Row: 1, admin, 123456, [email protected], 2019-06-27 18: 21: 07.0, 1, administrators, 1, 1, 2019-06-27 18:21 : 12.0, 3, system log, / logs
TRACE [main] - <== Row: 1, admin, 123456, [email protected], 2019-06-27 18: 21: 07.0, 2, ordinary users, 1, 1, 2019-06-27 18:21 : 12.0, 4, maintenance personnel, / persons
TRACE [main] - <== Row: 1, admin, 123456, [email protected], 2019-06-27 18: 21: 07.0, 2, ordinary users, 1, 1, 2019-06-27 18:21 : 12.0, 5, unit maintenance, / companies
TRACE [main] - <== Row: 1001, test, 123456, [email protected], 2019-06-27 18: 21: 07.0, 2, ordinary users, 1, 1, 2019-06-27 18:21 : 12.0, 4, maintenance personnel, / persons
TRACE [main] - <== Row: 1001, test, 123456, [email protected], 2019-06-27 18: 21: 07.0, 2, ordinary users, 1, 1, 2019-06-27 18:21 : 12.0, 5, unit maintenance, / companies
DEBUG [main] - <== Total: 7
Number of users: 2
Username: admin
Role name: Administrator
Permissions name: User Management
Permissions name: Role Management
Permissions Name: System Log
Role name: ordinary users
Permissions name: Maintenance personnel
Permissions name: Unit Maintenance
Username: test
Role name: ordinary users
Permissions name: Maintenance personnel
Permissions name: Unit Maintenance
As can be seen from the log, check out not only the role of information owned by the user, also check out the permission information contained in the role.
4. delay loading
Some students might say, the return of the role of information and permission information I do not necessarily use ah, each associated with so many queries a database table, good impact performance, ah, can not go when I use the role information that is acquired sysRoleList property database query it? The answer of course is energy, then how to achieve it?
Lazy loading required to achieve collection attribute tag fetchType, eager and lazy This property has two values, representing positive loading and delay loading.
Id because of the need to get all the right information corresponding to the role based on the role, so we must first define the following query in SysPrivilegeMapper.xml in:
<select id="selectPrivilegeByRoleId" resultMap="sysPrivilegeMap">
SELECT p.*
FROM sys_privilege p
INNER JOIN sys_role_privilege rp ON rp.privilege_id = p.id
WHERE rp.role_id = #{roleId}
</select>
Then add the following query in SysRoleMapper.xml in:
<resultMap id="rolePrivilegeListMapSelect" extends="roleMap"
type="com.zwwhnly.mybatisaction.model.SysRoleExtend">
<collection property="sysPrivilegeList" fetchType="lazy"
column="{roleId=id}"
select="com.zwwhnly.mybatisaction.mapper.SysPrivilegeMapper.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>
Above column="{roleId=id}"
in, roleId refers to the method specified selectPrivilegeByRoleId select the parameters, id refers to the query selectRoleByUserId query the role id.
Then add the following query in SysUserMapper.xml in:
<resultMap id="userRoleListMapSelect" extends="sysUserMap"
type="com.zwwhnly.mybatisaction.model.SysUserExtend">
<collection property="sysRoleList" fetchType="lazy"
select="com.zwwhnly.mybatisaction.mapper.SysRoleMapper.selectRoleByUserId"
column="{userId=id}"/>
</resultMap>
<select id="selectAllUserAndRolesSelect" resultMap="userRoleListMapSelect">
SELECT
u.id,
u.user_name,
u.user_password,
u.user_email,
u.create_time
FROM sys_user u
WHERE u.id = #{id}
</select>
Above column="{userId=id}"
the, userId refers to a method specified selectRoleByUserId select parameters, id refers query query selectAllUserAndRolesSelect out user id.
Then, in SysUserMapper interface, add the following method:
/**
* 通过嵌套查询获取指定用户的信息以及用户的角色和权限信息
*
* @param id
* @return
*/
SysUserExtend selectAllUserAndRolesSelect(Long id);
Finally, add the following test method SysUserMapperTest class:
@Test
public void testSelectAllUserAndRolesSelect() {
SqlSession sqlSession = getSqlSession();
try {
SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);
SysUserExtend sysUserExtend = sysUserMapper.selectAllUserAndRolesSelect(1L);
System.out.println("用户名:" + sysUserExtend.getUserName());
for (SysRoleExtend sysRoleExtend : sysUserExtend.getSysRoleList()) {
System.out.println("角色名:" + sysRoleExtend.getRoleName());
for (SysPrivilege sysPrivilege : sysRoleExtend.getSysPrivilegeList()) {
System.out.println("权限名:" + sysPrivilege.getPrivilegeName());
}
}
} finally {
sqlSession.close();
}
}
Running the test method, the log output as follows:
DEBUG [main] - ==> Preparing: SELECT u.id, u.user_name, u.user_password, u.user_email, u.create_time FROM sys_user u WHERE u.id = ?
DEBUG [main] - ==> Parameters: 1(Long)
TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_time
TRACE [main] - <== Row: 1, admin, 123456, [email protected], 2019-06-27 18:21:07.0
DEBUG [main] - <== Total: 1
Username: admin
DEBUG [main] - ==> Preparing: 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 = ?
DEBUG [main] - ==> Parameters: 1(Long)
TRACE [main] - <== Columns: id, role_name, enabled, create_by, create_time
TRACE [main] - <== Row: 1, the administrator, 1, 1, 2019-06-2718: 21: 12.0
TRACE [main] - <== Row: 2, ordinary users, 1, 1, 2019-06-2718: 21: 12.0
DEBUG [main] - <== Total: 2
Role name: Administrator
DEBUG [main] - ==> Preparing: SELECT p.* FROM sys_privilege p INNER JOIN sys_role_privilege rp ON rp.privilege_id = p.id WHERE rp.role_id = ?
DEBUG [main] - ==> Parameters: 1(Long)
TRACE [main] - <== Columns: id, privilege_name, privilege_url
TRACE [main] - <== Row: 1, user management, / users
TRACE [main] - <== Row: 2, role management, / roles
TRACE [main] - <== Row: 3, system log, / logs
DEBUG [main] - <== Total: 3
Permissions name: User Management
Permissions name: Role Management
Permissions Name: System Log
Role name: ordinary users
DEBUG [main] - ==> Preparing: SELECT p.* FROM sys_privilege p INNER JOIN sys_role_privilege rp ON rp.privilege_id = p.id WHERE rp.role_id = ?
DEBUG [main] - ==> Parameters: 2(Long)
TRACE [main] - <== Columns: id, privilege_name, privilege_url
TRACE [main] - <== Row: 4, maintenance personnel, / persons
TRACE [main] - <== Row: 5, maintenance units, / companies
DEBUG [main] - <== Total: 2
Permissions name: Maintenance personnel
Permissions name: Unit Maintenance
When the log careful analysis of the above, you will find only in the use of information and authority to the role of information, before the implementation of the corresponding database queries.
It should be noted that the delay in loading depends on MyBatis global configuration aggressiveLazyLoading, while in the previous blog to explain the association label, we have to configure it to false, so the results here is in line with our expectations:
<settings>
<!--其他配置-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
Explain in detail about the parameters, see the MyBatis from entry to the master (X): Use the association to achieve tags nested queries .
5. Summary
Use label collection implement nested query, use the properties are summarized as follows:
1) select: id, MyBatis extra another mapping query execution results of this query to get nested objects.
2) column: main column query results as a parameter nested queries, configuration such as column = "{prop1 = col1, prop2 = col2}", prop1 prop2 as a parameter, and a nested query.
3) fetchType: data loading, eager and lazy optional values, respectively, loading and delay loading active.
4) To use lazy loading, except that the lazy fetchType set, is also noted that the global configuration values aggressiveLazyLoading be false. This parameter defaults ture prior to version 3.4.5, version 3.4.5 from the beginning of the default value was changed to false.
5) lazyLoadTriggerMethods parameters MyBatis provided support queries directly trigger lazy loading property when triggered some methods, such as equals () method.
6. Source and reference
Source Address: https://github.com/zwwhnly/mybatis-action.git , welcome to download.
Liuzeng Hui "MyBatis from entry to the master."
The original is not easy, if that article can learn something, like a welcome point, a commentary on, off a note, this is my greatest motivation insist on writing.
If you are interested, please add my micro letter: zwwhnly , waiting for you to talk technology, workplace, work and other topics (PS: I am a programmer struggle in Shanghai).