关于树形权限关系
来源:互联网 发布:四川省教师网络培训 编辑:程序博客网 时间:2024/06/01 07:57
在做传统企业技术解决方案的过程中,经常会遇到将这样一种数据权限关系。
上级可见下级所有数据,同级之间权限不可见,下级不可见上级数据。并且业务场景经常会出现需要大量部门单位,此时如果部门关系存储在传统数据库中的方案就显得无力支撑。结构简单示例如图:
如果按这种结构,部门总数10万+,每日请求需求在百万到千万级别。部门关系数据改动较少,查询量很多,并且存在大量递归权限查询。为了支持针对此种业务场景,做了个redis的部门权限树,部门数据和权限数据分开存储,部门数据仍然采用关系型数据库mysql,关系数据存储在redis中,关键代码如下
treenode是树形结构的节点,包含两个部分node的上级节点,node的下级节点
public class TreeNode { //当前node节点的上级 private JSONArray nodeUpperList; //所有当前node节点的下级 private JSONArray nodeLowerList; /** * @return the nodeUpperList */ public JSONArray getNodeUpperList() { return nodeUpperList; } /** * @param nodeUpperList the nodeUpperList to set */ public void setNodeUpperList(JSONArray nodeUpperList) { this.nodeUpperList = nodeUpperList; } /** * @return the nodeLowerList */ public JSONArray getNodeLowerList() { return nodeLowerList; } /** * @param nodeLowerList the nodeLowerList to set */ public void setNodeLowerList(JSONArray nodeLowerList) { this.nodeLowerList = nodeLowerList; }}
定义treenode的新增结构,包含addSynDep添加节点,adjustAddSynDep调整添加后的上级节点。
/** * treerole 映射结构添加 * @param parentId:父级ID * @param nodeId:nodeID * @return rows =0 fail | >0 sucess */ public static Long addTreeRole(Long pNodeId, Long nodeId) throws Exception{ // TODO Auto-generated method stub //返回结果 Long rows = 0l; TreeNode treeNode = new TreeNode(); JSONArray arrObj = null; if( nodeId > 0 ){ //部门key String dRedisKey = nodeId.toString(); //父亲key String pRedisKey = pNodeId.toString(); //第一层节点并且父节点不存在 if( pNodeId == 0 && !redisBase.hexists(redisKey,pRedisKey) ){ //一级节点上级为空 arrObj = JSONArray.fromObject( "[]" ); treeNode.setNodeUpperList( arrObj ); treeNode.setNodeLowerList( arrObj ); rows = redisBase.hset(redisKey, dRedisKey, SerializeUtil.serialize(treeNode).toString()); }else if( pNodeId > 0 ){ //不是一级节点 //此处保证线程安全 添加节点进入映射结构 arrObj = addSynDep(dRedisKey,pRedisKey,pNodeId); } //***************当写入场景过多时 此处需要调整 BY Today //更新所有上级数据 if( arrObj != null){ @SuppressWarnings("rawtypes") Iterator iterator = arrObj.iterator(); while( iterator.hasNext() ){ String ppRedisKey = iterator.next().toString(); adjustAddSynDep(ppRedisKey,nodeId); } } } return rows; } //线程安全调整 private static synchronized void adjustAddSynDep(String ppRedisKey,Long nodeId){ String ppJsonString = redisBase.hget( redisKey,ppRedisKey ); TreeNode treeNode = (TreeNode) SerializeUtil.unserialize( ppJsonString.getBytes() ); JSONArray ppArrObj0 = treeNode.getNodeLowerList(); //将自己添加到上级的下级中 ppArrObj0.add( nodeId ); treeNode.setNodeLowerList( ppArrObj0 ); redisBase.hset(redisKey, ppRedisKey, SerializeUtil.serialize(treeNode).toString()); } //线程安全添加 private static synchronized JSONArray addSynDep(String dRedisKey,String pRedisKey,Long parentId){ if( redisBase.hexists(redisKey,dRedisKey) || !redisBase.hexists(redisKey,pRedisKey) ){ //部门存在 或者 父亲不存在 return null; } TreeNode treeNode = new TreeNode(); //取出父亲数据 String jsonString = redisBase.hget( redisKey,pRedisKey ); TreeNode pTreeNode = (TreeNode)SerializeUtil.unserialize(jsonString.getBytes()); //下级为空 JSONArray arrObj0 = JSONArray.fromObject( "[]" ); treeNode.setNodeLowerList( arrObj0 ); // 父亲的上级 JSONArray arrObj1 = pTreeNode.getNodeUpperList(); //追加自己的父亲 arrObj1.add(parentId); treeNode.setNodeUpperList( arrObj1 ); Long rows = redisBase.hset(redisKey, dRedisKey, SerializeUtil.serialize(treeNode).toString()); if( rows > 0 ){ //成功 返回自己的上级 return arrObj1; } //失败 return null;}
全部结构代码可查看https://github.com/zhaoshensky/treerole.git
阅读全文
1 0
- 关于树形权限关系
- 关于umask文件权限的关系
- 树形关系记录遍历
- 用树形结构分配权限
- 权限不挃令间癿关系:
- 关于权限
- 关于权限
- 关于权限
- 关于权限
- yx-树形结构展示,父子关系显示为完整树形
- 关于DRM父权限对象与子权限对象uid对应关系
- SpringMVC+ZTree实现树形菜单权限配置
- 关系数据库中存储树形结构
- oracle树形父子关系递归检索
- 树形数据在关系数据库的存储
- 如何使用mysql存储树形关系
- JPA树形结构实体关系映射
- 树形关系查询, connect by 用法
- SpringMVC配置返回JSON数据格式
- 话说C++中的左值、纯右值、将亡值
- 很少有人能说清楚listen函数的blacklog的含义, 那就让linux来说说吧!------笔试考过
- 算法题:复杂链表的复制
- poj1469 COURSES【二分图匹配】
- 关于树形权限关系
- 支持向量机(SVM)
- Ubuntu 安装 JDK 7 / JDK8 的两种方式
- UIPickerView控件中自定义显示的字体大小及样式
- 计数DP(Zero Escape,HDU 5389)
- 直接插入排序
- android冷启动优化
- linux管道pipe详解
- 深入思考0-1背包问题