1.引言
在日常的项目开发过程中,数据权限是保障数据安全的重要手段。MybatisPlus 作为 Mybatis 的增强工具,在为开发者提供便捷的数据库操作的同时,也应支持灵活的数据权限控制。
下面我们来看一下如何借助 MybatisPlus 实现自定义注解的数据权限。
2.数据权限拦截器的实现原理
主要是利用MybatisPlus中的租户功能进行改进,修改成可配置拦截规则,从而可以对不同的表进行配置不同的格则进行过滤
3.代码案例
3.1 配置自定义拦截器
/**
* 拦截器,并设置数据库类型为mysql
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(PermissionsConfig permissionsConfig) {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//实例化插件
interceptor.addInnerInterceptor(new TaskInterceptor(permissionsConfig));
return interceptor;
}
3.2 自定义拦截器(继续于MybatisPlus中的TenantLineInnerInterceptor类)
/**
* 数据权限统一过滤器
*
* @Author mxj
* @Date 2024/3/20 18:29
* @Version 2.0
*/
public class TaskInterceptor extends TenantLineInnerInterceptor {
public TaskInterceptor(PermissionsConfig permissionsConfig) {
super(new TenantLineHandler() {
/**
* 设置数据权限值(可以改成不同请求,或不同用户不同的做)
* @return
*/
@Override
public Expression getTenantId() {
return new LongValue(UserContextHolder.getInstance().currentUserId());
}
/**
* 设置过滤字段(可以改成动态字段)
* @return
*/
@Override
public String getTenantIdColumn() {
return "experiment_people";
}
/**
* 设置是否使用数据权限
* @param tableName 表名
* @return
*/
@Override
public boolean ignoreTable(String tableName) {
//true:表示忽略,false:表示执行过滤(可以概据自已的业务规则来判断)
return true;
}
});
}
/**
* 构建租户条件表达式
*
* @param table 表对象
* @param currentExpression 当前where条件
* @param whereSegment 所属Mapper对象全路径(在原租户拦截器功能中,这个参数并不需要参与相关判断)
* @return 租户条件表达式
* @see BaseMultiTableInnerInterceptor#buildTableExpression(Table, Expression, String)
*/
@Override
public Expression buildTableExpression(final Table table, final Expression currentExpression,
final String whereSegment) {
if (super.getTenantLineHandler().ignoreTable(table.getName())) {
return null;
}
//拼接查询条件语句(这里以json为例子)
String sqlExpression = parseJsonToSql(String.valueOf(super.getTenantLineHandler().getTenantId()),table.getAlias());
try {
return CCJSqlParserUtil.parseCondExpression(sqlExpression);
} catch (JSQLParserException e) {
throw new RuntimeException(e);
}
}
/**
* 拼接json查询条件
*
* @param jsonString
* @return
*/
private String parseJsonToSql(String jsonString, Alias alias) {
Assert.isTrue(StringUtils.isNotBlank(jsonString), () -> new BusinessException("数据权限id值不能为空"));
//拼接json查询方法
if(Objects.isNull(alias)){
return "JSON_CONTAINS("+ super.getTenantLineHandler().getTenantIdColumn() + ", '" + new StringValue(jsonString).getValue() + "','$')";
}
return "JSON_CONTAINS(" + alias.getName() + "." + super.getTenantLineHandler().getTenantIdColumn() + ", '" + new StringValue(jsonString).getValue() + "','$')";
}
@Override
protected void processInsert(Insert insert, int index, String sql, Object obj) {
}
/**
* update 语句处理
*/
@Override
protected void processUpdate(Update update, int index, String sql, Object obj) {
}
/**
* delete 语句处理
*/
@Override
protected void processDelete(Delete delete, int index, String sql, Object obj) {
}
}
4.详细教程可私信博主