mybatis【数据权限案例】

本贴最后更新于 1594 天前,其中的信息可能已经水流花落

数据权案例

mybatis 的 sql 构造,可能是我们程序猿每天都需经历的过程,前几天公司有了一个新的需求,做一个表结果的数据权限。

举个栗子:

某张表中维护这大量的客户信息,但是客户信息不是每个用户都看到,系统中维护一个树形结果的组结构,根据上下级的关系进行数据查看权限。 A a1 a2 a1,a2只能看到自己维护的信息。 A可以看到自己以及a1,a2以及自己信息。

其实这个问题从最开始分析的话,其实是可以在先将所有的数据查询先查询出来在进行处理,但是一般进行数据查询的时候,都是分页查询,这样的话一定会然查询出来数据和进行过滤出来的数据有区分,可能分页是查询 10 条 ,结果在过滤下没有 10 条数据,而且就在进行其他处理达到效果,但是在效率上是一定会有很大的影响的。

出发点只能走--sql 构造数据权限

思路设计:我只需要查询出来的表的某个字段,或者关联其他表某个字段匹配到某个用户权限集合就可以了

select *from customer cus left join user use on use.id = cus.createuser where cus.createuser in (.....所需要的数据权限)
  • 第一步

如何获取都某张表的所有集合,我们可以使用 mysql 的函数来进行构造出我们需要的数据,直接上脚本

image.png

CREATE DEFINER=`root`@`%` FUNCTION `getTableChildList`(rootId varchar(100)) RETURNS varchar(2000) CHARSET utf8 BEGIN DECLARE str varchar(2000); DECLARE cid varchar(2000); SET str = ''; SET cid = rootId; SET str = concat(str, ',', cid); SELECT group_concat(id) INTO cid FROM team where FIND_IN_SET(parent_id, cid) > 0; RETURN str; END

解释:team 是小组的表名 根据 id 找打它的 parent_id 的所对应的 id ,直至下级全部查询完毕!

1.表 名team 团队名称 --包含 了一个 leaderid 组长id parent_Id 上级团队 2.表 名 member 团队成员 memberid 成员id salesteamid 团队主键

这个函数可以写的更加适配一些,可以供应多个表结构使用。上代码

CREATE DEFINER=`root`@`%` FUNCTION `getTableChildList`( tablename varchar(100) ,rootId varchar(100)) RETURNS varchar(2000) CHARSET utf8 BEGIN DECLARE str varchar(2000); DECLARE cid varchar(2000); SET str = ''; SET cid = rootId; IF tablename ='A' then WHILE cid is not null DO SET str = concat(str, ',', cid); SELECT group_concat(id) INTO cid FROM A where FIND_IN_SET(parent_id, cid) > 0; END WHILE; ELSEIF tablename ='B' THEN WHILE cid is not null DO SET str = concat(str, ',', cid); SELECT group_concat(id) INTO cid FROM B where FIND_IN_SET(parent_id, cid) > 0; END WHILE; ELSEIF tablename ='C' THEN WHILE cid is not null DO SET str = concat(str, ',', cid); SELECT group_concat(id) INTO cid FROM C where FIND_IN_SET(parentid, cid) > 0; END WHILE; END IF; RETURN str; END

将函数脚本中,就可以实现我们需要的效果了 ,这里默认#{parameter.condition.loginUserId}是一定有值的,如果是自己卸载 mapper.xml 文件中话,要加上 if 判断操作。

SELECT * FROM customer cus LEFT JOIN USER USE ON USE.id = cus.createuser WHERE 1=1 <if test="parameter.condition != null and parameter.condition.loginUserId !=null and parameter.condition.loginUserId !='' "> and cus.createuser IN ( SELECT DISTINCT memberid FROM member WHERE salesteamid IN ( SELECT id FROM team WHERE FIND_IN_SET( id, getTableChildList ( 'team', ( SELECT id FROM team WHERE leaderid = #{parameter.condition.loginUserId} ) ) ) ) ) </if>

注意这样的写法还会存一个问题,如果我查询的一个人是组长,而且刚好我的下级没有了组员,为了系统的效率问题,可以加上一个 if 的语句进行判断

语法规则:IF(boolean condition,"true","false");

改进版效率提升,而且扩展性更好。

SELECT * FROM customer cus LEFT JOIN USER USE ON USE.id = cus.createuser WHERE 1=1 <if test="parameter.condition != null and parameter.condition.loginUserId !=null and parameter.condition.loginUserId !='' "> AND IF ( ( SELECT count( id ) FROM team WHERE FIND_IN_SET( id, getTableChildList ( 'team', ( SELECT id FROM team WHERE leaderid = #{parameter.condition.loginUserId} ) ) ) ) > 0, cus.createuser IN ( SELECT DISTINCT memberid FROM member WHERE salesteamid IN ( SELECT id FROM team WHERE FIND_IN_SET( id, getTableChildList ( 'team', ( SELECT id FROM team WHERE leaderid = #{parameter.condition.loginUserId} ) ) ) ) ) , cus.createuser IN ( SELECT DISTINCT memberid FROM member WHERE memberid = #{parameter.condition.loginUserId} ) ) </if>

扩展

  • IFNULL("t1","t2")【mysql】
  • ISNULL("t1","t2")【SQL Server / MS Access】
  • NVL("t1","t2")【Oracle】

第一参数如果为 null 使用第二个参数

  • IF(boolean condition,"true","false");

第一个参数布尔判断和为 true ,使用第二个参数,false 使用第三个 参数;和三目运算的规则一样。

  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    173 引用 • 414 回帖 • 357 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 531 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    32 引用 • 100 回帖
  • iOS

    iOS 是由苹果公司开发的移动操作系统,最早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,最初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。

    89 引用 • 150 回帖
  • 开源中国

    开源中国是目前中国最大的开源技术社区。传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。

    7 引用 • 86 回帖
  • 一些有用的避坑指南。

    69 引用 • 93 回帖
  • 创业

    你比 99% 的人都优秀么?

    81 引用 • 1395 回帖
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    135 引用 • 798 回帖
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    84 引用 • 414 回帖
  • frp

    frp 是一个可用于内网穿透的高性能的反向代理应用,支持 TCP、UDP、 HTTP 和 HTTPS 协议。

    17 引用 • 7 回帖 • 3 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖
  • 自由行
    1 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    10301 引用 • 46786 回帖 • 61 关注
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    187 引用 • 1021 回帖
  • Sillot

    Insights(注意当前设置 master 为默认分支)

    汐洛彖夲肜矩阵(Sillot T☳Converbenk Matrix),致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点。其中汐洛绞架(Sillot-Gibbet)基于自思源笔记(siyuan-note),前身是思源笔记汐洛版(更早是思源笔记汐洛分支),是智慧新录乄终端(多端融合,移动端优先)。

    主仓库地址:Hi-Windom/Sillot

    文档地址:sillot.db.sc.cn

    注意事项:

    1. ⚠️ 汐洛仍在早期开发阶段,尚不稳定
    2. ⚠️ 汐洛并非面向普通用户设计,使用前请了解风险
    3. ⚠️ 汐洛绞架基于思源笔记,开发者尽最大努力与思源笔记保持兼容,但无法实现 100% 兼容
    29 引用 • 25 回帖 • 142 关注
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    167 引用 • 597 回帖 • 1 关注
  • LeetCode

    LeetCode(力扣)是一个全球极客挚爱的高质量技术成长平台,想要学习和提升专业能力从这里开始,充足技术干货等你来啃,轻松拿下 Dream Offer!

    209 引用 • 72 回帖
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 505 关注
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    43 引用 • 44 回帖 • 1 关注
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 260 关注
  • VirtualBox

    VirtualBox 是一款开源虚拟机软件,最早由德国 Innotek 公司开发,由 Sun Microsystems 公司出品的软件,使用 Qt 编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。

    10 引用 • 2 回帖 • 15 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    139 引用 • 269 回帖 • 1 关注
  • 代码片段

    代码片段分为 CSS 与 JS 两种代码,添加在 [设置 - 外观 - 代码片段] 中,这些代码会在思源笔记加载时自动执行,用于改善笔记的样式或功能。

    用户在该标签下分享代码片段时需在帖子标题前添加 [css] [js] 用于区分代码片段类型。

    225 引用 • 1589 回帖 • 1 关注
  • sts
    2 引用 • 2 回帖 • 247 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 442 关注
  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 349 关注
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    76 引用 • 1742 回帖