作者 朱兆平

优化sql树形结构的查询-改为查询出所有的数据后用steam进行children Set

... ... @@ -28,6 +28,9 @@ public interface ROLEMapper {
List<ROLE> findAll(@Param("roleName") String roleName,
@Param("type") String type);
List<ROLE> findAllWithOutTree(@Param("roleName") String roleName,
@Param("type") String type);
int updateByPrimaryKeySelective(ROLE record);
int updateByPrimaryKey(ROLE record);
... ...
... ... @@ -20,6 +20,8 @@ public interface USERSMapper {
List<USERS> selectByUsername(String userName);
USERS selectByUsernameWithRoleAndPerm(String userName);
List<USERS> selectAllUser(USERS users);
}
... ...
... ... @@ -11,6 +11,7 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
... ... @@ -21,8 +22,9 @@ import java.util.*;
@Service
public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource{
@Autowired
@Resource
PERMISSIONMapper permissionMapper;
AntPathMatcher pathMatcher = new AntPathMatcher();
private HashMap<String, Collection<ConfigAttribute>> map =null;
... ...
... ... @@ -8,16 +8,15 @@ import com.tianbo.warehouse.annotation.cache.annotation.RedisCacheEvict;
import com.tianbo.warehouse.annotation.cache.annotation.RedisCacheable;
import com.tianbo.warehouse.dao.PERMISSIONMapper;
import com.tianbo.warehouse.model.PERMISSION;
import com.tianbo.warehouse.model.ROLE;
import com.tianbo.warehouse.service.PermissionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Service("PermissionService")
... ... @@ -84,6 +83,17 @@ public class PermissionServiceImp implements PermissionService {
try {
//查询所有菜单
List<PERMISSION> allMenu = permissionMapper.findByUserId(userId);
List<PERMISSION> allTreeMenu = allMenu.stream()
.filter(perm -> perm.getParentId() == 0)
.map((perm) ->{
perm.setChildren(getChildrens(perm, allMenu));
return perm;
}).sorted((befor,after) -> {
return (befor.getPermissionOrder() == null ? 0 : Integer.parseInt(befor.getPermissionOrder())) - (after.getPermissionOrder() == null ? 0 : Integer.parseInt(after.getPermissionOrder()));
}).collect(Collectors.toList());
// //根节点
// List<PERMISSION> rootMenu = new ArrayList<PERMISSION>();
// for (PERMISSION nav : allMenu) {
... ... @@ -105,7 +115,7 @@ public class PermissionServiceImp implements PermissionService {
*
*/
data.put("success", "true");
data.put("list", allMenu);
data.put("list", allTreeMenu);
return data;
} catch (Exception e) {
data.put("success", "false");
... ... @@ -184,7 +194,32 @@ public class PermissionServiceImp implements PermissionService {
@Override
// @RedisCacheable(cacheKey = "getUserMenuTreeByUserId")
public List<PERMISSION> getUserMenuTreeByUserId(@NotNull Integer userId) {
return permissionMapper.getUserMenuTreeByUserId(userId);
List<PERMISSION> loginedUserMenus = permissionMapper.getUserMenuTreeByUserId(userId);
List<PERMISSION> loginedUserMenusTree = loginedUserMenus.stream()
.filter(perm -> perm.getParentId() == 0)
.map((perm) ->{
perm.setChildren(getChildrens(perm, loginedUserMenus));
return perm;
}).sorted((befor,after) -> {
return (befor.getPermissionOrder() == null ? 0 : Integer.parseInt(befor.getPermissionOrder())) - (after.getPermissionOrder() == null ? 0 : Integer.parseInt(after.getPermissionOrder()));
}).collect(Collectors.toList());
return loginedUserMenusTree;
}
//递归查找所有菜单的子菜单
private List<PERMISSION> getChildrens(PERMISSION root, List<PERMISSION> listAll) {
List<PERMISSION> children = listAll.stream().filter(categoryEntity -> {
return categoryEntity.getParentId().equals(root.getPermissionId());
}).map(categoryEntity -> {
//1、找到子菜单(递归)
categoryEntity.setChildren(getChildrens(categoryEntity, listAll));
return categoryEntity;
}).sorted((befor,after) -> {
return (befor.getPermissionOrder() == null ? 0 : Integer.parseInt(befor.getPermissionOrder())) - (after.getPermissionOrder() == null ? 0 : Integer.parseInt(after.getPermissionOrder()));
}).collect(Collectors.toList());
return children;
}
}
... ...
... ... @@ -15,32 +15,76 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
@Service(value = "roleService")
public class RoleServiceImp implements RoleService{
@Autowired
@Resource
private ROLEMapper roleMapper;
@Autowired
@Resource
private RolePermissionMapper rolePermissionMapper;
@Autowired
@Resource
DepartmentMapper departmentMapper;
@Autowired
PermissionService permissionService;
/**
*
* @param pageNum
* @param pageSize
* @param roleName
* @param type
* @return 返回树形结构
*/
@Override
public PageInfo<ROLE> findAll(int pageNum, int pageSize, String roleName, String type){
Page<ROLE> page = PageHelper.startPage(pageNum,pageSize);
List<ROLE> list = roleMapper.findAll(roleName, type);
// List<ROLE> treeList = list.stream()
// .filter(role -> role.getParentid() == 0)
// .map((role) ->{
// role.setChildren(getChildrens(role, list));
// return role;
// })
// .sorted(Comparator.comparingInt(ROLE::getRsort))
// .collect(Collectors.toList());
PageInfo<ROLE> result = new PageInfo<ROLE>(list);
return result;
}
/**
* sql查询出所有的组织机构,再根据结果集进行children Set
* @param roleName
* @param type
* @return
*/
public PageInfo<ROLE> findAllWithOutTree(String roleName, String type){
List<ROLE> list = roleMapper.findAllWithOutTree(roleName, type);
List<ROLE> treeList = list.stream()
.filter(role -> role.getParentid() == 0)
.map((role) ->{
role.setChildren(getChildrens(role, list));
return role;
})
.sorted(Comparator.comparingInt(ROLE::getRsort))
.collect(Collectors.toList());
PageInfo<ROLE> result = new PageInfo<ROLE>(treeList);
return result;
}
@Override
public int insertSelective(ROLE record){
return roleMapper.insertSelective(record);
... ... @@ -88,4 +132,21 @@ public class RoleServiceImp implements RoleService{
}
}
//递归查找所有菜单的子菜单
private List<ROLE> getChildrens(ROLE root, List<ROLE> listAll) {
List<ROLE> children = listAll.stream().filter(categoryEntity -> {
return categoryEntity.getParentid().equals(root.getRoleId());
}).map(categoryEntity -> {
//1、找到子菜单(递归)
categoryEntity.setChildren(getChildrens(categoryEntity, listAll));
return categoryEntity;
}).sorted(Comparator.comparingInt(ROLE::getRsort))
.collect(Collectors.toList());
return children;
}
}
... ...
... ... @@ -44,11 +44,30 @@ public class UserServiceImpl implements UserService{
@Override
public USERS loadByUsername(String username){
List<USERS> userList = usersMapper.selectByUsername(username);
USERS userInfo = usersMapper.selectByUsernameWithRoleAndPerm(username);
//新SQL MYBATIS SQL 绑定role跟perm的方法,以减少数据库查询次数
if (userInfo!=null){
if (userInfo.getRoles()!=null && userInfo.getRoles().isEmpty()){
List<ROLE> topRoles = roleMapper.selectTopByChildID(userInfo.getRoles().get(0).getRoleId());
topRoles.removeAll(Collections.singleton(null));
if (!topRoles.isEmpty()){
userInfo.setCompanyId(topRoles.get(0).getRoleId());
userInfo.setCompanyName(topRoles.get(0).getRoleName());
topRoles.get(0).setChildren(null);
topRoles.get(0).setPermissions(null);
userInfo.setCompanyInfo(topRoles.get(0));
}
}
return userInfo;
}
//旧方法
if (userList != null && userList.size() > 0) {
USERS user = userList.get(0);
//获取用户角色列表,用户没有配置相关组织机构时,获取不到权限
//获取用户角色列表-非树形结构,用户没有配置相关组织机构时,获取不到权限
List<ROLE> roleList = roleMapper.findRolesByUserId(user.getUserId());
//用户未绑定组织机构时会查询出null数组信息,现象为All elements are null
... ... @@ -69,7 +88,7 @@ public class UserServiceImpl implements UserService{
user.setRoles(roleList);
}
//用户权限列表
//用户权限列表-非树形
List<PERMISSION> permissionList = permissionService.findByUserIdWithLogin(user.getUserId());
if (!permissionList.isEmpty()){
user.setPermissions(permissionList);
... ... @@ -92,6 +111,7 @@ public class UserServiceImpl implements UserService{
for (USERS user: list) {
// List<PERMISSION> permissionList = permissionMapper.findByUserId(user.getUserId());
// user.setPermissions(permissionList);
//为了前端role配置的适配
List<ROLE> roleList = roleMapper.findRolesByUserId(user.getUserId());
user.setRoles(roleList);
}
... ...
... ... @@ -101,7 +101,7 @@ FROM
LEFT JOIN role R ON R.role_id= RP.role_id
where P.url = #{permissionUrl,jdbcType=VARCHAR} ORDER BY permission_order
</select>
<select id="findByUserId" parameterType="java.lang.Integer" resultMap="treeResultMap">
<select id="findByUserId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
SELECT
P.*
FROM
... ... @@ -129,7 +129,6 @@ where P.url = #{permissionUrl,jdbcType=VARCHAR} ORDER BY permission_order
)
)
)
AND P.parent_id = 0
ORDER BY permission_order
</select>
<select id="findByUserIdWithLogin" parameterType="java.lang.Integer" resultMap="BaseResultMap">
... ... @@ -325,14 +324,12 @@ where P.url = #{permissionUrl,jdbcType=VARCHAR} ORDER BY permission_order
where permission_id = #{permissionId,jdbcType=INTEGER}
</update>
<select id="getUserMenuTreeByUserId" parameterType="java.lang.Integer" resultMap="treeMap">
<select id="getUserMenuTreeByUserId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
SELECT
P.*
FROM
permission P
WHERE
parent_id = 0
AND
ismenu = 1
AND
P.permission_id IN (
... ...
... ... @@ -13,9 +13,36 @@
<result column="business_license" jdbcType="VARCHAR" property="businessLicense" />
<result column="departmentId" jdbcType="VARCHAR" property="departmentid" />
<result column="mq_code" jdbcType="VARCHAR" property="mqcode" />
</resultMap>
<resultMap id="TreeWithPermResultMap" type="com.tianbo.warehouse.model.ROLE">
<id column="role_id" jdbcType="INTEGER" property="roleId" />
<result column="role_name" jdbcType="VARCHAR" property="roleName" />
<result column="role_sign" jdbcType="VARCHAR" property="roleSign" />
<result column="description" jdbcType="VARCHAR" property="description" />
<result column="type" jdbcType="VARCHAR" property="type" />
<result column="parentId" jdbcType="INTEGER" property="parentid" />
<result column="rsort" jdbcType="INTEGER" property="rsort" />
<result column="customs_reg_code" jdbcType="VARCHAR" property="customsRegCode" />
<result column="business_license" jdbcType="VARCHAR" property="businessLicense" />
<result column="departmentId" jdbcType="VARCHAR" property="departmentid" />
<result column="mq_code" jdbcType="VARCHAR" property="mqcode" />
<collection column="role_id" javaType="java.util.ArrayList" ofType="com.tianbo.warehouse.model.PERMISSION" property="permissions" select="com.tianbo.warehouse.dao.PERMISSIONMapper.getRolePermisson" />
<collection column="role_id" property="children" select="selectByParentId" />
</resultMap>
<resultMap id="TreeWithResultMap" type="com.tianbo.warehouse.model.ROLE">
<id column="role_id" jdbcType="INTEGER" property="roleId" />
<result column="role_name" jdbcType="VARCHAR" property="roleName" />
<result column="role_sign" jdbcType="VARCHAR" property="roleSign" />
<result column="description" jdbcType="VARCHAR" property="description" />
<result column="type" jdbcType="VARCHAR" property="type" />
<result column="parentId" jdbcType="INTEGER" property="parentid" />
<result column="rsort" jdbcType="INTEGER" property="rsort" />
<result column="customs_reg_code" jdbcType="VARCHAR" property="customsRegCode" />
<result column="business_license" jdbcType="VARCHAR" property="businessLicense" />
<result column="departmentId" jdbcType="VARCHAR" property="departmentid" />
<result column="mq_code" jdbcType="VARCHAR" property="mqcode" />
<collection column="role_id" property="children" select="selectByParentId" />
</resultMap>
<sql id="Base_Column_List">
role_id, role_name, role_sign, description, type, parentId, rsort, customs_reg_code,
business_license, departmentId, mq_code
... ... @@ -26,7 +53,7 @@
from role
where role_id = #{roleId,jdbcType=INTEGER}
</select>
<select id="selectByParentId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
<select id="selectByParentId" parameterType="java.lang.Integer" resultMap="TreeWithResultMap">
select
<include refid="Base_Column_List" />
from role
... ... @@ -205,18 +232,20 @@ WHERE
where role_id = #{roleId,jdbcType=INTEGER}
</update>
<select id="findAll" parameterType="java.lang.String" resultMap="BaseResultMap">
<select id="findAll" parameterType="java.lang.String" resultMap="TreeWithResultMap">
SELECT
<include refid="Base_Column_List" />
FROM role
where parentId=0
and 1=1
<where>
parentId = 0
<if test="roleName != '' and roleName !=null">
and role_name = #{roleName, jdbcType=VARCHAR}
</if>
<if test="type != '' and type !=null">
and type like '%' #{type} '%'
</if>
</where>
order by rsort
</select>
<select id="findRolesByUserId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
SELECT
... ... @@ -227,4 +256,19 @@ WHERE
LEFT JOIN role R ON R.role_id= UR.role_id
where U.user_id = #{userId,jdbcType=INTEGER}
</select>
<select id="findAllWithOutTree" parameterType="java.lang.String" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List" />
FROM role
<where>
<if test="roleName != '' and roleName !=null">
and role_name = #{roleName, jdbcType=VARCHAR}
</if>
<if test="type != '' and type !=null">
and type like '%' #{type} '%'
</if>
</where>
order by parentId,rsort
</select>
</mapper>
... ...
... ... @@ -32,6 +32,35 @@
<result column="age" property="age" jdbcType="INTEGER" />
<result column="company_id" property="companyId" jdbcType="INTEGER" />
</resultMap>
<resultMap id="WithRoleAndPermResultMap" type="com.tianbo.warehouse.model.USERS" extends="BaseResultMap">
<collection property="roles" javaType="java.util.ArrayList" ofType="com.tianbo.warehouse.model.ROLE">
<result column="role_id" jdbcType="INTEGER" property="roleId" />
<result column="role_name" jdbcType="VARCHAR" property="roleName" />
<result column="role_sign" jdbcType="VARCHAR" property="roleSign" />
<result column="rdescription" jdbcType="VARCHAR" property="description" />
<result column="type" jdbcType="VARCHAR" property="type" />
<result column="parentId" jdbcType="INTEGER" property="parentid" />
<result column="rsort" jdbcType="INTEGER" property="rsort" />
<result column="customs_reg_code" jdbcType="VARCHAR" property="customsRegCode" />
<result column="business_license" jdbcType="VARCHAR" property="businessLicense" />
<result column="departmentId" jdbcType="VARCHAR" property="departmentid" />
<result column="mq_code" jdbcType="VARCHAR" property="mqcode" />
</collection>
<collection property="permissions" javaType="java.util.ArrayList" ofType="com.tianbo.warehouse.model.PERMISSION">
<result column="permission_id" property="permissionId" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="permission_order" property="permissionOrder" jdbcType="VARCHAR" />
<result column="pdescription" property="description" jdbcType="VARCHAR" />
<result column="ismenu" property="ismenu" jdbcType="BOOLEAN" />
<result column="hidden" property="hidden" jdbcType="BOOLEAN" />
<result column="parent_id" property="parentId" jdbcType="INTEGER" />
<result column="path" property="path" jdbcType="VARCHAR" />
<result column="url" property="url" jdbcType="VARCHAR" />
<result column="method" property="method" jdbcType="VARCHAR" />
<result column="iconCls" property="iconCls" jdbcType="VARCHAR" />
<result column="component" property="component" jdbcType="VARCHAR" />
</collection>
</resultMap>
<sql id="Base_Column_List" >
user_id, username, password, birthday, sex, address, state, mobilePhone, creatTime,
updateTime, userFace, realName, email, age,company_id
... ... @@ -51,6 +80,27 @@
from users
where username = #{username,jdbcType=VARCHAR}
</select>
<select id="selectByUsernameWithRoleAndPerm" resultMap="WithRoleAndPermResultMap" parameterType="java.lang.String" >
select
u.user_id, username, password, birthday, sex, address, state, mobilePhone, creatTime,
updateTime, userFace, realName, email, age,company_id,
r.role_id, role_name, role_sign, r.description as rdescription, `type`, parentId, rsort, customs_reg_code,
business_license, departmentId, mq_code,
p.permission_id, `name`, permission_order, p.description as pdescription, ismenu,hidden,parent_id,
path, url, method, iconCls, component
from
(select
<include refid="Base_Column_List" />
from users
where username = 'nmms') u
left join user_role ur on u.user_id = ur.user_id
left join role r on r.role_id = ur.role_id
left join role_permission rp on r.role_id = rp.role_id
left join permission p on rp.permission_id = p.permission_id
</select>
<select id="selectAllUser" resultMap="BaseResultMap" parameterType="com.tianbo.warehouse.model.USERS" >
select
<!-- <include refid="Base_Column_List" />-->
... ...
package com.tianbo.warehouse;
import com.tianbo.warehouse.WarehouseApplication;
import com.tianbo.warehouse.security.CustomUserDetailService;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = WarehouseApplication.class,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Slf4j
public class UserTest {
@Autowired
CustomUserDetailService customUserDetailService;
@Test
public void contextLoads() {
UserDetails u = customUserDetailService.loadUserByUsername("nmms");
log.info("ok");
}
}
... ...