有一个代码的设计问题,大佬们帮帮我

145 天前
 tongjiann

简单介绍一下情况。

  1. 我们是用的是 jdk8+mybatis+MybatisPlus+diboot(小众的 MP 的增强,没看见过可忽略)的后端项目
  2. 每个业务表中都有一个 period(会计期间)字段

现在有一个 PM 提了一个很容易理解但是很傻逼的 Feature:

只有管理员开放指定 period 之后,才能对指定 period 的业务表数据进行增删改查(增删改已经做限制,采用下面第二种方法。),否则都不允许(返回空或提示权限不足) 管理员无视上面一条要求

初步想法

  1. 在所有的查询语句执行前在代码层添加可查询的 period 列表。
    • 比如 select * from table a where id = 'xxx',那就改成 select * from table a where id = 'xxx' and period in (valid_period_list);
  2. 对所有的查询出来的数据进行校验。由于增删改单次进行的对象的数据量较小,所以在增删改操作进行前做一次查询取出所有被查询的数据并判断 period ,这样损耗较小,目前可以接受。但是当查询的时候使用系统方法我认为会严重损耗性能。
    • 比如 select * from table a where id = 'xxx'。在查询出数据之后,在代码层进行一次校验,判断 period 是否合理。

请问一下大佬们对这个 Feature 有什么比较好的实现经验吗,或者说比较好的 idea

5016 次点击
所在节点    程序员
43 条回复
tongjiann
145 天前
@andy2415 #19 谢谢,还贴了代码
xibeifeng
145 天前
我理解的这个问题本质是数据权限问题,要考虑:1.控制数据权限的字段有哪些,这里是 period ,后续有没有其他字段需要配置,比如多个字段组合,是否可能寻在这种场景 ? 2.这个判断逻辑放在哪里,数据库、后端、前端。3.具体场景可能还有一些其他问题,反正就是跟时空之神做交易
具体方案的话:1.数据量小,字段固定,直接页面加载的时候,先把 period 缓存一下到本地 2.放后端,写一个切面加上注解,数据库做一张配置表,计算好每个人配置的 period ,然后在查询之前对查询条件做过滤,后续也能支持多字段控制数据权限,也可以通过加上注解实现逻辑可插拔 3.数据库硬编码写死逻辑,或者构建试图
SoviaPhilo
145 天前
巧了, 我手上有个项目有类似的需求, 而且也用上面的方式做了统一处理

然后一年以后我就不再用这玩意儿了。
一个问题是管理员需要操作全量数据, 意味着要维护 selectIgnore
另一个问题是出现了相似的相对含义字段,类比一下就是业务增加了第二个 会计期间,而且要基于这个做逻辑
第三个问题是业务性条件,非显式地填充事实上增加了潜在成本

考虑到 PO 的视野根本看不了这么远, 直接用你的方案 1 算了
MaxYang666
145 天前
如果操作的表不是太多的话,方案 1 就可以,如果操作的表数量比较多,还是想办法抽一个中间层出来比较好
BiChengfei
145 天前
方案 1 ,加个 Mybatis 拦截器就行
meeop
145 天前
如果 period 只是表示数据是否可查询的话,可以考虑做两张表,一张草稿标,一张在线查询表,在线表都是可查的,草稿表则是没进入发布态的数据,可发布时刻再插入在线表
NX2023
145 天前
第一个想到的是 casbin👀
lmq2582609
145 天前
这个看着和若依的数据权限处理有点像,不过若依的是按部门分数据权限,每个表都有 deptId 字段,可以参考看看。
原理还是 mybatis 拦截器修改 sql 语句来实现的,这样分页功能不会受到影响。
lmq2582609
145 天前
http://doc.ruoyi.vip/ruoyi/document/htsc.html#%E6%95%B0%E6%8D%AE%E6%9D%83%E9%99%90
boqiqita
145 天前
补充下数据库里的数据量和 QPS 呗
M48A1
145 天前
@needpp 我见过的是根据角色不同使用不同的 function
tongjiann
145 天前
@boqiqita #30 目前已有总数据量千万吧,月度数据增量大概百万,QPS 不高,可能就月底用一下?属于绩效系统,从外部取数,然后算出绩效,面向的对象是主要还是绩效专员
ningmengzhensuan
145 天前
第一种的话,你要维护所有的表修改,改动量太大,而且后期你们产品再添加新的类似需求的时候,那你还得改全部的 SQL 查询,第二种确实耗费性能
你可以把这两个实现聚合起来,用拦截器+注解,新增一个注解,给需要设定权限限制的 SQL 查询添加上
在拦截器那里添加前置拦截,判断权限,后置处理数据可以再进行特殊判断,添加一些权限、角色配置
这样的话,对代码的渗透较低,可以扩充变更
nealHuang
145 天前
我们都用 kjqj 来表示 会计期间
xxmaqzas
145 天前
查询走视图
zhazi
145 天前
MMDeJeVS3GtMVLeu
145 天前
我是前端,如果对一个请求做前、后的处理,用 axios 有拦截器这个概念。
搜了一下 sql 也有类似的概念,mybatis 拦截器 https://juejin.cn/post/7116757450274897957

除非项目特别简单、后期不动了,否则强烈不推荐第一种方式:
1 、每个地方加,找起来很痛苦
2 、文档不够好的话,对后面开发的开发来说就是灾难了,因为别人很容易遗漏这个条件
tongjiann
145 天前
@justyeh #37 我描述的不够准确,首先,肯定不可能在每个业务类中修改代码实现这个功能,最起码也要抽一层出来,尽可能减少与业务的关联性,保证后续新增业务表也不需要修改这里的代码。我最终的实现方案是参照 17L 的方式,写一个拦截器,统一在 SQL 执行前进行拦截,然后判断,如果需要就注入 SQL
crz
145 天前
刚好最近看过,postgres 有 row level security ,数据库层级对访问/操作进行控制,就是对应这种需求的,不知道你们用的数据库有没有类似实现
tongjiann
145 天前
感谢大家的回复,最终根据 17L 的建议进行了修改

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1060204

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX