提交 d681ca8b 编写于 作者: J jarvis

feat: 1. 增加记录修改前后sql功能 2. 增加使用expression修改别名3. 增加默认不进行拦截的sqlId

上级 7b5089a6
...@@ -13,9 +13,11 @@ import lombok.extern.slf4j.Slf4j; ...@@ -13,9 +13,11 @@ import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.JSQLParserException; import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Alias; import net.sf.jsqlparser.expression.Alias;
import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.ExpressionVisitorAdapter;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression; import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.parser.CCJSqlParserManager; import net.sf.jsqlparser.parser.CCJSqlParserManager;
import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table; import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.*; import net.sf.jsqlparser.statement.select.*;
import org.apache.ibatis.executor.Executor; import org.apache.ibatis.executor.Executor;
...@@ -29,7 +31,6 @@ import org.springframework.web.util.pattern.PathPatternParser; ...@@ -29,7 +31,6 @@ import org.springframework.web.util.pattern.PathPatternParser;
import java.io.StringReader; import java.io.StringReader;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
import static com.central.common.datascope.mp.sql.handler.SqlHandler.ALIAS_SYNBOL; import static com.central.common.datascope.mp.sql.handler.SqlHandler.ALIAS_SYNBOL;
...@@ -66,7 +67,7 @@ public class DataScopeInnerInterceptor implements InnerInterceptor { ...@@ -66,7 +67,7 @@ public class DataScopeInnerInterceptor implements InnerInterceptor {
} }
@Override @Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
if(CollUtil.isEmpty(dataScopeProperties.getIgnoreSqls())|| !dataScopeProperties.getIgnoreSqls().contains(ms.getId())){ if(CollUtil.isEmpty(dataScopeProperties.getIgnoreSqls())|| !dataScopeProperties.getIgnoreSqls().contains(ms.getId())){
PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql); PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
String sql = boundSql.getSql(); String sql = boundSql.getSql();
...@@ -227,19 +228,26 @@ public class DataScopeInnerInterceptor implements InnerInterceptor { ...@@ -227,19 +228,26 @@ public class DataScopeInnerInterceptor implements InnerInterceptor {
* @throws JSQLParserException * @throws JSQLParserException
*/ */
private SelectBody reformWhere(PlainSelect select, String whereSql, List<String> aliasName) throws JSQLParserException { private SelectBody reformWhere(PlainSelect select, String whereSql, List<String> aliasName) throws JSQLParserException {
Expression where = select.getWhere();
// todo 处理exists // todo 处理exists
if(StrUtil.isNotBlank(whereSql)&& CollUtil.isNotEmpty(aliasName)){ if(StrUtil.isNotBlank(whereSql)&& CollUtil.isNotEmpty(aliasName)){
String andWhereSql = aliasName.stream() for (String alias : aliasName) {
.map(item -> whereSql.replaceAll(ALIAS_SYNBOL, StrUtil.isNotBlank(item) ? item : ""))
.collect(Collectors.joining(" and "));
if(StrUtil.isNotBlank(andWhereSql)){
Expression expression = CCJSqlParserUtil Expression expression = CCJSqlParserUtil
.parseCondExpression(andWhereSql); .parseCondExpression(whereSql);
if(ObjectUtil.isNull(where)){ expression.accept(new ExpressionVisitorAdapter(){
@Override
public void visit(Column column) {
if(Objects.isNull(column.getTable())|| ALIAS_SYNBOL.equals(column.getTable().toString())){
Table table = new Table();
table.setAlias(new Alias(alias));
column.setTable(table);
}
}
});
if(ObjectUtil.isNull(select.getWhere())){
select.setWhere(expression); select.setWhere(expression);
}else { }else {
AndExpression andExpression = new AndExpression(where, expression); AndExpression andExpression = new AndExpression(select.getWhere(), expression);
select.setWhere(andExpression); select.setWhere(andExpression);
} }
} }
......
package com.central.common.datascope.mp.interceptor;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import java.sql.SQLException;
/**
* 示例
*
* @author jarvis create by 2023/2/2
*/
@Slf4j
public class EnableQuerySqlLogInnerInterceptor implements InnerInterceptor{
private InnerInterceptor delegate;
public EnableQuerySqlLogInnerInterceptor(InnerInterceptor delegate) {
Assert.notNull(delegate, "委派类不能为空");
this.delegate = delegate;
}
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
String sql = boundSql.getSql();
log.info("执行mapperId{},原始sql为{}", ms.getId(), sql);
delegate.beforeQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql);
log.info("执行mapperId{}, 修改sql为{}", ms.getId(), mpBs.sql());
}
}
...@@ -40,7 +40,7 @@ public class CreatorDataScopeSqlHandler implements SqlHandler{ ...@@ -40,7 +40,7 @@ public class CreatorDataScopeSqlHandler implements SqlHandler{
List<SysRole> roleList = userService.findRolesByUserId(user.getId()); List<SysRole> roleList = userService.findRolesByUserId(user.getId());
return StrUtil.isBlank(dataScopeProperties.getCreatorIdColumnName()) return StrUtil.isBlank(dataScopeProperties.getCreatorIdColumnName())
||CollUtil.isEmpty(roleList) ||CollUtil.isEmpty(roleList)
|| roleList.stream().anyMatch(item-> Objects.nonNull(item.getDataScope()) || DataScope.ALL.equals(item.getDataScope())) || roleList.stream().anyMatch(item-> Objects.isNull(item.getDataScope()) || DataScope.ALL.equals(item.getDataScope()))
? DO_NOTHING: ? DO_NOTHING:
// 这里确保有配置权限范围控制的字段 // 这里确保有配置权限范围控制的字段
// 1. 如果没有配置角色的情况默认采用只读全部的记录 // 1. 如果没有配置角色的情况默认采用只读全部的记录
......
package com.central.common.properties; package com.central.common.properties;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.ImmutableSet;
import lombok.Data; import lombok.Data;
import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Collections; import java.util.Collections;
...@@ -15,20 +15,30 @@ import java.util.Set; ...@@ -15,20 +15,30 @@ import java.util.Set;
* @author jarvis create by 2023/1/8 * @author jarvis create by 2023/1/8
*/ */
@ConfigurationProperties(prefix = "zlt.datascope") @ConfigurationProperties(prefix = "zlt.datascope")
@Getter @Data
public class DataScopeProperties { public class DataScopeProperties {
private static final Set<String> INGORE_SQL_ID = ImmutableSet
.of("com.central.user.mapper.findRolesByUserId"
, "com.central.user.mapper.SysUserMapper.selectList"
, "com.central.user.mapper.SysUserRoleMapper.findRolesByUserId"
, "com.central.user.mapper.SysRoleMenuMapper.findMenusByRoleIds");
/** /**
* 是否开启权限控制 * 是否开启权限控制
*/ */
private Boolean enabled = Boolean.FALSE; private Boolean enabled = Boolean.FALSE;
/**
* 是否开启打印sql的修改情况
*/
private Boolean enabledSqlDebug = Boolean.FALSE;
/** /**
* 在includeTables的匹配符中过滤某几个表不需要权限的,仅enabled=true * 在includeTables的匹配符中过滤某几个表不需要权限的,仅enabled=true
*/ */
private Set<String> ignoreTables = Collections.singleton("SYS*"); private Set<String> ignoreTables = Collections.emptySet();
/** /**
* 指定某几条sql不执行权限控制, 仅enabled=true生效 * 指定某几条sql不执行权限控制, 仅enabled=true生效
*/ */
private Set<String> ignoreSqls = Collections.emptySet(); private Set<String> ignoreSqls = INGORE_SQL_ID;
/** /**
* 指定某几个表接受权限控制,仅enabled=true,默认当开启时全部表 * 指定某几个表接受权限控制,仅enabled=true,默认当开启时全部表
*/ */
...@@ -38,27 +48,12 @@ public class DataScopeProperties { ...@@ -38,27 +48,12 @@ public class DataScopeProperties {
* 指定需要的字段名 * 指定需要的字段名
*/ */
private String creatorIdColumnName; private String creatorIdColumnName;
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public void setIgnoreTables(Set<String> ignoreTables) {
HashSet<String> ignoreSet = new HashSet<>();
CollUtil.addAll(ignoreSet, ignoreTables);
CollUtil.addAll(ignoreSet, this.ignoreTables);
this.ignoreTables = ignoreSet;
}
public void setIgnoreSqls(Set<String> ignoreSqls) { public void setIgnoreSqls(Set<String> ignoreSqls) {
this.ignoreSqls = ignoreSqls; Set<String> ingoreSet = new HashSet<>();
} ingoreSet.addAll(INGORE_SQL_ID);
if(CollUtil.isNotEmpty(ignoreSqls)){
public void setIncludeTables(Set<String> includeTables) { ingoreSet.addAll(ignoreSqls);
this.includeTables = includeTables; }
} this.ignoreSqls = ingoreSet;
public void setCreatorIdColumnName(String creatorIdColumnName) {
this.creatorIdColumnName = creatorIdColumnName;
} }
} }
...@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; ...@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.central.common.datascope.mp.interceptor.DataScopeInnerInterceptor; import com.central.common.datascope.mp.interceptor.DataScopeInnerInterceptor;
import com.central.common.datascope.mp.interceptor.EnableQuerySqlLogInnerInterceptor;
import com.central.common.datascope.mp.sql.handler.CreatorDataScopeSqlHandler; import com.central.common.datascope.mp.sql.handler.CreatorDataScopeSqlHandler;
import com.central.common.datascope.mp.sql.handler.SqlHandler; import com.central.common.datascope.mp.sql.handler.SqlHandler;
import com.central.common.properties.DataScopeProperties; import com.central.common.properties.DataScopeProperties;
...@@ -61,7 +62,9 @@ public class MybatisPlusAutoConfigure { ...@@ -61,7 +62,9 @@ public class MybatisPlusAutoConfigure {
mpInterceptor.addInnerInterceptor(tenantInterceptor); mpInterceptor.addInnerInterceptor(tenantInterceptor);
} }
if(dataScopeProperties.getEnabled()){ if(dataScopeProperties.getEnabled()){
mpInterceptor.addInnerInterceptor(new DataScopeInnerInterceptor(dataScopeProperties, sqlHandler)); DataScopeInnerInterceptor dataScopeInnerInterceptor = new DataScopeInnerInterceptor(dataScopeProperties, sqlHandler);
mpInterceptor.addInnerInterceptor(Boolean.TRUE.equals(dataScopeProperties.getEnabledSqlDebug())
? new EnableQuerySqlLogInnerInterceptor(dataScopeInnerInterceptor): dataScopeInnerInterceptor);
} }
mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return mpInterceptor; return mpInterceptor;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册