数据权限
数据权限
项目启动时将数据权限表加入redis中,因为很多接口都需要设置数据权限,故提高响应性能。
对于每个新进来的线程,如果不需要数据权限的配置,那么先对当前线程设置不需要数据权限,这里做的处理是在该线程调用的那个接口的方法里,在这个方法调用数据库操作前,先在threadlocal中加入一个notSqlPower的标识。
当进行数据库操作的时候,配置好的mybatis拦截器拦截到prepare方法,先判断是否是select方法,如果不是则放行,如果是查询方法,则再判断是否有threadlocal中的notSqlPower标识,若存在标识则证明无需进行数据权限,若存在则继续。若根据登录后存放的threadlocal中的用户信息,若是超级管理员则无需数据权限。
用户在登录将该用户的权限信息存入redis中,其实就是维护这个用户所属的公司信息,他的角色对应的权限信息,都是用一个hashmap去收集起来,然后存入到redis里方便后续使用。
获取到原始的sql,随后动态拼接上对应的公司,公路**(即管理高速权限和管理单位权限)**等信息在sql的where条件后和连接条件后面
具体实现:
redis的key为”road_qr_data_table”,存的是下面这个表的信息
sys_data_table
查询用户具有的具体权限用下面三张表:
sys_userrole,sys_data_type,user_data_type
用户角色表(sys_userrole):主要是管理用户和角色的对应关系
数据权限结构表(sys_data_type):用于存储存在哪些数据权限,即数据权限的类型,当前只有高速和公司两种类型,即有效的数据只有两条
用户数据权限表(user_data_type):用于存放每条数据为员工id,角色id,类型id,数据id**(特指公司id或者是高速id)**
通过这三张表,能得出当前这个用户所具有的公司和高速的一个列表:
举例说明:
公司-公司id1
公司-公司id2
高速-高速id1
高速-高速id2
高速-高速id3
类似于上面的这样一个列表
查询到这样一个列表之后,可以转换为Map<String, List
具体流程是解析得到原始的sql,然后判断是否有嵌套的子查询
如果有,则单独将子查询提取出来转换为Select,并将???
根据查到的hashmap的数据分别将条件拼接到on和where的条件上,构造成新的sql语句并返回。
分页
分页的道理也是同理,都是自定义一个拦截器去拦截要执行的sql,如果是select就拦截下来,根据自定义的注解判断是否需要分页,如果需要分页则动态拼接sql到后面
具体是在请求的时候就将limit的两个参数就已经保存到了threadlocal中,如果没有则默认为1,10,然后在将这两个参数动态拼接到原始sql后面