java 项目通用数据权限设计

文章目录

  • 前言
  • 一、常见的数据权限
  • 二、通用数据权限设计思路
    • 通用权限示例(灵活配置最简单方式)
      • 两个表
      • 业务理解
      • 最终拼接出来的sql 为:
  • 总结


前言

权限一般分为操作权限和数据权限

操作权限: 菜单,页面,按钮
数据权限: 能看到的数据,包括各种页面的数据范围


一、常见的数据权限

例如:

  • 多租户,每个租户只能看到各自租户内部的数据

一般通过字段级别过滤,mybatis/mybatis-plus通常通过拦截器自动凭拼接或 手动拼接;

  • 单独配置某个特定的数据权限: 例如之前的项目,单独分配区域权限,这样每个人可以灵活看到区域数据,达到数据权限的配置;

一般是特定的数据权限,类似于用户级别的属性一样,每次查询用户 单独查询,类似于菜单权限数据一样; 这里推荐将此类数据权限放在 角色 上

  • 本文讲解,通用数据权限: 即类似于多租户的感觉,适用于所有表的过滤

与多租户不同的是,多租户的数据权限字段是固定的,不灵活,这里根据当前项目,分享两种灵活思路!

二、通用数据权限设计思路

  1. 通过类似枚举定义,在每个角色中,增加一个属性为数据范围, 分为各个等级; 其中等级的限制条件可以是各种维度的一种: 机构,区域,组织,然后类似于通过等级的不同,生成sql片段手动拼接到查询条件中;

例如: 当前组织以及子组织 (不是迭代)
sql片段为: org_code = 1 or org_code = 1-1
等级可以是: 当前组织; 子组织; 当前以及子组织; 当前以及迭代子集;当前组织的三级组织;等等

  1. 通过一种灵活的配置,达到不同字段的范围限制;

思路是通过exist / in 然后限制某个字段的值,这个字段是灵活的,可以自由配置,然后也是通过生成sql片段,手动拼接到查询中

通用权限示例(灵活配置最简单方式)

两个表

  • 普通业务表 category
  • 配置限制表 limit_table
CREATE DATABASE /*!32312 IF NOT EXISTS*/`test` /*!40100 DEFAULT CHARACTER SET latin1 */;

USE `test`;

/*Table structure for table `category` */

DROP TABLE IF EXISTS `category`;

CREATE TABLE `category` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '名称',
  `pid` int(11) DEFAULT NULL COMMENT '父节点id',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;

/*Data for the table `category` */

insert  into `category`(`id`,`name`,`pid`) values 
(1,'文学',NULL),
(2,'童书',1),
(3,'社会科学',1),
(4,'经济学',1),
(5,'科普百科',2),
(7,'法律',3);

/*Table structure for table `limit_table` */

DROP TABLE IF EXISTS `limit_table`;

CREATE TABLE `limit_table` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `field` varchar(55) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '字段',
  `field_value` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '值',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='留言表';

/*Data for the table `limit_table` */

insert  into `limit_table`(`id`,`field`,`field_value`) values 
(1,'name','文学'),
(2,'name','童书'),
(3,'title','你好'),
(4,'title','不好');

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

业务理解

我想通过限制表,限制业务表中的数据,具体是通过field中的name字段限制,限制条件在限制表的field_value中

最终拼接出来的sql 为:

SELECT c.* FROM category c WHERE EXISTS (SELECT 1 FROM limit_table b WHERE b.field = ‘name’ AND b.field_value = c.name)

sql过滤结果

只有调用的人才知道具体要用哪个字段,限定哪张表,所以应该用哪个字段,以及用哪个表的哪个属性限制,需要调用的人传入;例如本示例中, b.field = ‘name’ 中的 name 和 b.field_value = c.name 中的 c.name 为调用方传入的一对对应关系!!


这里最牛的思路我认为有两个:

  1. 通过exists 的特性加速查询,还是通过特性,达到了b.field_value = c.name 过滤效果
  2. 通过灵活的配置,以及传入参数实现了数据权限sql片段生成的灵活性

总结

这里不做扩展,其实这里仅仅是最简单的方式,即直接通过限制表达到对于业务表的数据过滤,那么其实我们还可以通过其他方式限制;
例如:

  • 通过字典组限制,那么exists内部在拼接之前可能需要二次处理;
  • 通过sql语句配置限定条件,那么我们需要拼接sql语句,甚至当sql语句中有变量,我们需要解析后,再拼接到sql片段中;
  • 通过多个条件的限制,这里是单一条件,那么我可能有多个条件,这时候,这样的单表就无法满足了,我们需要创建更多的配置表,达到条件的配置以及组合( and / or 等),设置包括字典组和sql解析,然后最终形成一个复杂的sql片段;

单个条件组内的sql 需要 unin all
多个条件默认为 or

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/630630.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

kafka用java收发消息

用java客户端代码来对kafka收发消息 具体代码如下 package com.cool.interesting.kafka;import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.consumer.ConsumerRecords; i…

MP3解码入门(基于libhelix)

主要参考资料: 【Arduino Linux】基于 Helix 解码库实现 MP3 音频播放: https://blog.csdn.net/weixin_42258222/article/details/122640413 libhelix-mp3: https://github.com/ultraembedded/libhelix-mp3/tree/master 目录 一、MP3文件二、MP3 解码库三、libhelix-mp3库3.1 …

Java 自然排序和比较器排序区别?Comparable接口和Comparator比较器区别?

注:如果你对排序不理解,请您耐心看完,你一定会明白的。文章通俗易懂。建议用idea运行一下案例。 1)自然排序和比较器排序的区别? 自然排序是对象本身定义的排序规则,由对象实现 Comparable 接口&#xff…

思科模拟器--2.静态路由和默认路由配置24.5.15

首先,创建三个路由器和两个个人电脑。 接着,配置两台电脑的IP,子网掩码和默认网关 对Router 0,进行以下命令: 对Router进行以下命令: 对Router2进行以下命令: 本实验完成。 验证:PC…

Leetcode39.组合总和

文章目录 题目描述解题思路重复子集剪枝 代码 题目 参考题解 题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返…

Android Studio kotlin 转 Java

一. 随笔记录 java代码可以转化成kotlin代码,当然 Kotlin 反过来也可以转java 在Android Studio中 可以很方便的操作 AS 环境:Android Studio Iguana | 2023.2.1 二. 操作步骤 1.步骤 顶部Tools ----->Kotlin ------>Show Kotlin Bytecode 步…

错误: 找不到或无法加载主类问题(已解决)

今天在虚拟机中安装了idea2023.2的版本,运行代码时发现错误找不到主类! 直接说结论: 我先clean了一下target,然后重新build,发现maven报错了,idea2023.2默认使用了内置的maven,然后我切换了一下…

ThreadLocal,一次到位

一、定义 ThreadLocal是线程私有变量&#xff0c;用于保存每个线程的私有数据。 那么什么情况下需要进行线程隔离 二、源码分析 public class ThreadLocalTest01 {ThreadLocal<Integer> t new ThreadLocal<>();public void test() {t.set(1);Integer integer…

MT3036 第一节离数课后

思路&#xff1a; 这道题与之前的表达式求值题目不同的是&#xff0c;有not这个单目运算符。而且如果表达式错误&#xff0c;要输入error。 把true和false成为操作数&#xff0c;把and or not成为运算符。 考虑error的情况&#xff1a; 1.and 和 or是双目运算符&#xff0c…

文心一言指令多样化,你知道的有哪些?

文心一言的指令非常多样化&#xff0c;可以根据用户的需求和场景进行灵活调整。以下是一些常见的文心一言指令示例&#xff1a; 知识问答&#xff1a; 帮我解释一下什么是芯片&#xff1f;中国的历史上有哪些重要的朝代&#xff1f;人工智能在未来会有哪些发展趋势&#xff1f;…

表白成功率百分百的向女朋友表白网页源代码,向女友表白HTML源代码

表白成功率百分百的向女朋友表白网页源代码&#xff0c;向女友表白HTML源代码 效果&#xff1a; 完整代码下载地址&#xff1a;向女友表白HTML源代码 <!DOCTYPE html> <!--STATUS OK--> <html><head><meta http-equiv"Content-Type" c…

P8805 [蓝桥杯 2022 国 B] 机房

P8805 [蓝桥杯 2022 国 B] 机房 分析 是一道lca题目&#xff0c;可以直接套模板 前缀和处理点权 具体思路&#xff1a; 1.n台电脑用n-1条网线相连&#xff0c;任意两个节点之间有且仅有一条路径&#xff08;拆分成各自到公共祖先节点的路径——lca&#xff09;&#xff1b;…

CAD插入文字到另一图形样式变相同

CAD从一张图形复制到另外一张图形后&#xff0c;文字样式变成一样是因为两张图所用的文字样式名称一样&#xff0c;但是样式里面的使用字体样式不一样。如下图所示&#xff0c;找到工具栏中的注释 &#xff0c;点击文字样式。里面就会显示当前图形中使用的样式名称及其对应的字…

TINA 使用教程

常用功能 分析-电气规则检查&#xff1a;短路&#xff0c;断路等分析- 直流分析 交流分析 瞬态分析 视图-分离曲线 由于输出的容性负载导致的振荡 增加5欧电阻后OK 横扫参数 添加横扫曲线的电阻&#xff0c;选择R3&#xff1a;8K-20K PWL和WAV文件的支持 示例一&#xff1a;…

ubuntu在conda环境中使用 pip install -r requirements.txt但是没有安装在虚拟环境中

whereis pip pip listubuntu在conda环境中使用pip install lpips0.1.3 但是安装在了这里 Requirement already satisfied: lpips0.1.3 in /home/uriky/anaconda3/lib/python3.11/site-packages (0.1.3) 就会出现黄色波浪&#xff0c;未在虚拟环境中安装包 解决办法1&#xff1…

[NOIP2011 普及组] 瑞士轮

[NOIP2011 普及组] 瑞士轮 题目背景 在双人对决的竞技性比赛&#xff0c;如乒乓球、羽毛球、国际象棋中&#xff0c;最常见的赛制是淘汰赛和循环赛。前者的特点是比赛场数少&#xff0c;每场都紧张刺激&#xff0c;但偶然性较高。后者的特点是较为公平&#xff0c;偶然性较低…

如何使用JMeter测试导入接口/导出接口?

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号&#xff1a;互联网杂货铺&#xff0c;回复1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 今天上班&#xff0c;被开发问了一个问题&#xff1a;JM…

html基础(全)

html简介 目录 什么是网页 什么是 HTML 常用浏览器 WebE标准的构成 基本语法概述 第一个HTML页面 文档类型声明标签 lang 语言种类 字符集 标题标签 段落和换行标签 文本格式化标签 div和span标签 图像标签和路径 超链接标签 表格的主要作用 表头单元格标签 列…

[华为OD] C卷 dfs 特殊加密算法 100

题目&#xff1a; 有一种特殊的加密算法&#xff0c;明文为一段数字串&#xff0c;经过密码本查找转换&#xff0c;生成另一段密文数字串。 规则如下 1•明文为一段数字串由0-9组成 2.密码本为数字0-9组成的二维数组 3•需要按明文串的数字顺序在密码本里找到同样的数字串…

基于SpringBoot设计模式之创建型设计模式·工厂方法模式

文章目录 介绍开始架构图样例一定义工厂定义具体工厂&#xff08;上衣、下装&#xff09;定义产品定义具体生产产品&#xff08;上衣、下装&#xff09; 测试样例 总结优点缺点与抽象工厂不同点 介绍 在 Factory Method模式中&#xff0c;父类决定实例的生成方式&#xff0c;但…