From ee7c1128d6c5d3b2c2eaeac7a36b7965c845bde3 Mon Sep 17 00:00:00 2001 From: houzhongjian <houzhongyi@126.com> Date: 星期五, 02 八月 2024 09:44:22 +0800 Subject: [PATCH] 删除无用代码 --- /dev/null | 533 ----------------------------------------------------------- 1 files changed, 0 insertions(+), 533 deletions(-) diff --git a/iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java b/iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java deleted file mode 100644 index b3856d8..0000000 --- a/iailab-framework/iailab-common-biz-data-permission/src/main/java/com/iailab/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java +++ /dev/null @@ -1,641 +0,0 @@ -package com.iailab.framework.datapermission.core.db; - -import cn.hutool.core.collection.CollUtil; -import com.iailab.framework.common.util.collection.SetUtils; -import com.iailab.framework.datapermission.core.rule.DataPermissionRule; -import com.iailab.framework.datapermission.core.rule.DataPermissionRuleFactory; -import com.iailab.framework.mybatis.core.util.MyBatisUtils; -import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; -import com.baomidou.mybatisplus.core.toolkit.PluginUtils; -import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport; -import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import net.sf.jsqlparser.expression.*; -import net.sf.jsqlparser.expression.operators.conditional.AndExpression; -import net.sf.jsqlparser.expression.operators.conditional.OrExpression; -import net.sf.jsqlparser.expression.operators.relational.ExistsExpression; -import net.sf.jsqlparser.expression.operators.relational.ExpressionList; -import net.sf.jsqlparser.expression.operators.relational.InExpression; -import net.sf.jsqlparser.schema.Table; -import net.sf.jsqlparser.statement.delete.Delete; -import net.sf.jsqlparser.statement.select.*; -import net.sf.jsqlparser.statement.update.Update; -import org.apache.ibatis.executor.Executor; -import org.apache.ibatis.executor.statement.StatementHandler; -import org.apache.ibatis.mapping.BoundSql; -import org.apache.ibatis.mapping.MappedStatement; -import org.apache.ibatis.mapping.SqlCommandType; -import org.apache.ibatis.session.ResultHandler; -import org.apache.ibatis.session.RowBounds; - -import java.sql.Connection; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - -/** - * 数据权限拦截器,通过 {@link DataPermissionRule} 数据权限规则,重写 SQL 的方式来实现 - * 主要的 SQL 重写方法,可见 {@link #builderExpression(Expression, List)} 方法 - * - * 整体的代码实现上,参考 {@link com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor} 实现。 - * 所以每次 MyBatis Plus 升级时,需要 Review 下其具体的实现是否有变更! - * - * @author iailab - */ -@RequiredArgsConstructor -public class DataPermissionDatabaseInterceptor extends JsqlParserSupport implements InnerInterceptor { - - private final DataPermissionRuleFactory ruleFactory; - - @Getter - private final MappedStatementCache mappedStatementCache = new MappedStatementCache(); - - @Override // SELECT 场景 - public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { - // 获得 Mapper 对应的数据权限的规则 - List<DataPermissionRule> rules = ruleFactory.getDataPermissionRule(ms.getId()); - if (mappedStatementCache.noRewritable(ms, rules)) { // 如果无需重写,则跳过 - return; - } - - PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql); - try { - // 初始化上下文 - ContextHolder.init(rules); - // 处理 SQL - mpBs.sql(parserSingle(mpBs.sql(), null)); - } finally { - // 添加是否需要重写的缓存 - addMappedStatementCache(ms); - // 清空上下文 - ContextHolder.clear(); - } - } - - @Override // 只处理 UPDATE / DELETE 场景,不处理 INSERT 场景(因为 INSERT 不需要数据权限) - public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) { - PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh); - MappedStatement ms = mpSh.mappedStatement(); - SqlCommandType sct = ms.getSqlCommandType(); - if (sct == SqlCommandType.UPDATE || sct == SqlCommandType.DELETE) { - // 获得 Mapper 对应的数据权限的规则 - List<DataPermissionRule> rules = ruleFactory.getDataPermissionRule(ms.getId()); - if (mappedStatementCache.noRewritable(ms, rules)) { // 如果无需重写,则跳过 - return; - } - - PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql(); - try { - // 初始化上下文 - ContextHolder.init(rules); - // 处理 SQL - mpBs.sql(parserMulti(mpBs.sql(), null)); - } finally { - // 添加是否需要重写的缓存 - addMappedStatementCache(ms); - // 清空上下文 - ContextHolder.clear(); - } - } - } - - @Override - protected void processSelect(Select select, int index, String sql, Object obj) { - processSelectBody(select.getSelectBody()); - List<WithItem> withItemsList = select.getWithItemsList(); - if (!CollectionUtils.isEmpty(withItemsList)) { - withItemsList.forEach(this::processSelectBody); - } - } - - /** - * update 语句处理 - */ - @Override - protected void processUpdate(Update update, int index, String sql, Object obj) { - final Table table = update.getTable(); - update.setWhere(this.builderExpression(update.getWhere(), table)); - } - - /** - * delete 语句处理 - */ - @Override - protected void processDelete(Delete delete, int index, String sql, Object obj) { - delete.setWhere(this.builderExpression(delete.getWhere(), delete.getTable())); - } - - // ========== 和 TenantLineInnerInterceptor 一致的逻辑 ========== - - protected void processSelectBody(SelectBody selectBody) { - if (selectBody == null) { - return; - } - if (selectBody instanceof PlainSelect) { - processPlainSelect((PlainSelect) selectBody); - } else if (selectBody instanceof WithItem) { - WithItem withItem = (WithItem) selectBody; - processSelectBody(withItem.getSubSelect().getSelectBody()); - } else { - SetOperationList operationList = (SetOperationList) selectBody; - List<SelectBody> selectBodyList = operationList.getSelects(); - if (CollectionUtils.isNotEmpty(selectBodyList)) { - selectBodyList.forEach(this::processSelectBody); - } - } - } - - /** - * 处理 PlainSelect - */ - protected void processPlainSelect(PlainSelect plainSelect) { - //#3087 github - List<SelectItem> selectItems = plainSelect.getSelectItems(); - if (CollectionUtils.isNotEmpty(selectItems)) { - selectItems.forEach(this::processSelectItem); - } - - // 处理 where 中的子查询 - Expression where = plainSelect.getWhere(); - processWhereSubSelect(where); - - // 处理 fromItem - FromItem fromItem = plainSelect.getFromItem(); - List<Table> list = processFromItem(fromItem); - List<Table> mainTables = new ArrayList<>(list); - - // 处理 join - List<Join> joins = plainSelect.getJoins(); - if (CollectionUtils.isNotEmpty(joins)) { - mainTables = processJoins(mainTables, joins); - } - - // 当有 mainTable 时,进行 where 条件追加 - if (CollectionUtils.isNotEmpty(mainTables)) { - plainSelect.setWhere(builderExpression(where, mainTables)); - } - } - - private List<Table> processFromItem(FromItem fromItem) { - // 处理括号括起来的表达式 - while (fromItem instanceof ParenthesisFromItem) { - fromItem = ((ParenthesisFromItem) fromItem).getFromItem(); - } - - List<Table> mainTables = new ArrayList<>(); - // 无 join 时的处理逻辑 - if (fromItem instanceof Table) { - Table fromTable = (Table) fromItem; - mainTables.add(fromTable); - } else if (fromItem instanceof SubJoin) { - // SubJoin 类型则还需要添加上 where 条件 - List<Table> tables = processSubJoin((SubJoin) fromItem); - mainTables.addAll(tables); - } else { - // 处理下 fromItem - processOtherFromItem(fromItem); - } - return mainTables; - } - - /** - * 处理where条件内的子查询 - * <p> - * 支持如下: - * 1. in - * 2. = - * 3. > - * 4. < - * 5. >= - * 6. <= - * 7. <> - * 8. EXISTS - * 9. NOT EXISTS - * <p> - * 前提条件: - * 1. 子查询必须放在小括号中 - * 2. 子查询一般放在比较操作符的右边 - * - * @param where where 条件 - */ - protected void processWhereSubSelect(Expression where) { - if (where == null) { - return; - } - if (where instanceof FromItem) { - processOtherFromItem((FromItem) where); - return; - } - if (where.toString().indexOf("SELECT") > 0) { - // 有子查询 - if (where instanceof BinaryExpression) { - // 比较符号 , and , or , 等等 - BinaryExpression expression = (BinaryExpression) where; - processWhereSubSelect(expression.getLeftExpression()); - processWhereSubSelect(expression.getRightExpression()); - } else if (where instanceof InExpression) { - // in - InExpression expression = (InExpression) where; - Expression inExpression = expression.getRightExpression(); - if (inExpression instanceof SubSelect) { - processSelectBody(((SubSelect) inExpression).getSelectBody()); - } - } else if (where instanceof ExistsExpression) { - // exists - ExistsExpression expression = (ExistsExpression) where; - processWhereSubSelect(expression.getRightExpression()); - } else if (where instanceof NotExpression) { - // not exists - NotExpression expression = (NotExpression) where; - processWhereSubSelect(expression.getExpression()); - } else if (where instanceof Parenthesis) { - Parenthesis expression = (Parenthesis) where; - processWhereSubSelect(expression.getExpression()); - } - } - } - - protected void processSelectItem(SelectItem selectItem) { - if (selectItem instanceof SelectExpressionItem) { - SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem; - if (selectExpressionItem.getExpression() instanceof SubSelect) { - processSelectBody(((SubSelect) selectExpressionItem.getExpression()).getSelectBody()); - } else if (selectExpressionItem.getExpression() instanceof Function) { - processFunction((Function) selectExpressionItem.getExpression()); - } - } - } - - /** - * 处理函数 - * <p>支持: 1. select fun(args..) 2. select fun1(fun2(args..),args..)<p> - * <p> fixed gitee pulls/141</p> - * - * @param function - */ - protected void processFunction(Function function) { - ExpressionList parameters = function.getParameters(); - if (parameters != null) { - parameters.getExpressions().forEach(expression -> { - if (expression instanceof SubSelect) { - processSelectBody(((SubSelect) expression).getSelectBody()); - } else if (expression instanceof Function) { - processFunction((Function) expression); - } - }); - } - } - - /** - * 处理子查询等 - */ - protected void processOtherFromItem(FromItem fromItem) { - // 去除括号 - while (fromItem instanceof ParenthesisFromItem) { - fromItem = ((ParenthesisFromItem) fromItem).getFromItem(); - } - - if (fromItem instanceof SubSelect) { - SubSelect subSelect = (SubSelect) fromItem; - if (subSelect.getSelectBody() != null) { - processSelectBody(subSelect.getSelectBody()); - } - } else if (fromItem instanceof ValuesList) { - logger.debug("Perform a subQuery, if you do not give us feedback"); - } else if (fromItem instanceof LateralSubSelect) { - LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem; - if (lateralSubSelect.getSubSelect() != null) { - SubSelect subSelect = lateralSubSelect.getSubSelect(); - if (subSelect.getSelectBody() != null) { - processSelectBody(subSelect.getSelectBody()); - } - } - } - } - - /** - * 处理 sub join - * - * @param subJoin subJoin - * @return Table subJoin 中的主表 - */ - private List<Table> processSubJoin(SubJoin subJoin) { - List<Table> mainTables = new ArrayList<>(); - if (subJoin.getJoinList() != null) { - List<Table> list = processFromItem(subJoin.getLeft()); - mainTables.addAll(list); - mainTables = processJoins(mainTables, subJoin.getJoinList()); - } - return mainTables; - } - - /** - * 处理 joins - * - * @param mainTables 可以为 null - * @param joins join 集合 - * @return List<Table> 右连接查询的 Table 列表 - */ - private List<Table> processJoins(List<Table> mainTables, List<Join> joins) { - // join 表达式中最终的主表 - Table mainTable = null; - // 当前 join 的左表 - Table leftTable = null; - - if (mainTables == null) { - mainTables = new ArrayList<>(); - } else if (mainTables.size() == 1) { - mainTable = mainTables.get(0); - leftTable = mainTable; - } - - //对于 on 表达式写在最后的 join,需要记录下前面多个 on 的表名 - Deque<List<Table>> onTableDeque = new LinkedList<>(); - for (Join join : joins) { - // 处理 on 表达式 - FromItem joinItem = join.getRightItem(); - - // 获取当前 join 的表,subJoint 可以看作是一张表 - List<Table> joinTables = null; - if (joinItem instanceof Table) { - joinTables = new ArrayList<>(); - joinTables.add((Table) joinItem); - } else if (joinItem instanceof SubJoin) { - joinTables = processSubJoin((SubJoin) joinItem); - } - - if (joinTables != null) { - - // 如果是隐式内连接 - if (join.isSimple()) { - mainTables.addAll(joinTables); - continue; - } - - // 当前表是否忽略 - Table joinTable = joinTables.get(0); - - List<Table> onTables = null; - // 如果不要忽略,且是右连接,则记录下当前表 - if (join.isRight()) { - mainTable = joinTable; - if (leftTable != null) { - onTables = Collections.singletonList(leftTable); - } - } else if (join.isLeft()) { - onTables = Collections.singletonList(joinTable); - } else if (join.isInner()) { - if (mainTable == null) { - onTables = Collections.singletonList(joinTable); - } else { - onTables = Arrays.asList(mainTable, joinTable); - } - mainTable = null; - } - - mainTables = new ArrayList<>(); - if (mainTable != null) { - mainTables.add(mainTable); - } - - // 获取 join 尾缀的 on 表达式列表 - Collection<Expression> originOnExpressions = join.getOnExpressions(); - // 正常 join on 表达式只有一个,立刻处理 - if (originOnExpressions.size() == 1 && onTables != null) { - List<Expression> onExpressions = new LinkedList<>(); - onExpressions.add(builderExpression(originOnExpressions.iterator().next(), onTables)); - join.setOnExpressions(onExpressions); - leftTable = joinTable; - continue; - } - // 表名压栈,忽略的表压入 null,以便后续不处理 - onTableDeque.push(onTables); - // 尾缀多个 on 表达式的时候统一处理 - if (originOnExpressions.size() > 1) { - Collection<Expression> onExpressions = new LinkedList<>(); - for (Expression originOnExpression : originOnExpressions) { - List<Table> currentTableList = onTableDeque.poll(); - if (CollectionUtils.isEmpty(currentTableList)) { - onExpressions.add(originOnExpression); - } else { - onExpressions.add(builderExpression(originOnExpression, currentTableList)); - } - } - join.setOnExpressions(onExpressions); - } - leftTable = joinTable; - } else { - processOtherFromItem(joinItem); - leftTable = null; - } - } - - return mainTables; - } - - // ========== 和 TenantLineInnerInterceptor 存在差异的逻辑:关键,实现权限条件的拼接 ========== - - /** - * 处理条件 - * - * @param currentExpression 当前 where 条件 - * @param table 单个表 - */ - protected Expression builderExpression(Expression currentExpression, Table table) { - return this.builderExpression(currentExpression, Collections.singletonList(table)); - } - - /** - * 处理条件 - * - * @param currentExpression 当前 where 条件 - * @param tables 多个表 - */ - protected Expression builderExpression(Expression currentExpression, List<Table> tables) { - // 没有表需要处理直接返回 - if (CollectionUtils.isEmpty(tables)) { - return currentExpression; - } - - // 第一步,获得 Table 对应的数据权限条件 - Expression dataPermissionExpression = null; - for (Table table : tables) { - // 构建每个表的权限 Expression 条件 - Expression expression = buildDataPermissionExpression(table); - if (expression == null) { - continue; - } - // 合并到 dataPermissionExpression 中 - dataPermissionExpression = dataPermissionExpression == null ? expression - : new AndExpression(dataPermissionExpression, expression); - } - - // 第二步,合并多个 Expression 条件 - if (dataPermissionExpression == null) { - return currentExpression; - } - if (currentExpression == null) { - return dataPermissionExpression; - } - // ① 如果表达式为 Or,则需要 (currentExpression) AND dataPermissionExpression - if (currentExpression instanceof OrExpression) { - return new AndExpression(new Parenthesis(currentExpression), dataPermissionExpression); - } - // ② 如果表达式为 And,则直接返回 where AND dataPermissionExpression - return new AndExpression(currentExpression, dataPermissionExpression); - } - - /** - * 构建指定表的数据权限的 Expression 过滤条件 - * - * @param table 表 - * @return Expression 过滤条件 - */ - private Expression buildDataPermissionExpression(Table table) { - // 生成条件 - Expression allExpression = null; - for (DataPermissionRule rule : ContextHolder.getRules()) { - // 判断表名是否匹配 - String tableName = MyBatisUtils.getTableName(table); - if (!rule.getTableNames().contains(tableName)) { - continue; - } - // 如果有匹配的规则,说明可重写。 - // 为什么不是有 allExpression 非空才重写呢?在生成 column = value 过滤条件时,会因为 value 不存在,导致未重写。 - // 这样导致第一次无 value,被标记成无需重写;但是第二次有 value,此时会需要重写。 - ContextHolder.setRewrite(true); - - // 单条规则的条件 - Expression oneExpress = rule.getExpression(tableName, table.getAlias()); - if (oneExpress == null){ - continue; - } - // 拼接到 allExpression 中 - allExpression = allExpression == null ? oneExpress - : new AndExpression(allExpression, oneExpress); - } - - return allExpression; - } - - /** - * 判断 SQL 是否重写。如果没有重写,则添加到 {@link MappedStatementCache} 中 - * - * @param ms MappedStatement - */ - private void addMappedStatementCache(MappedStatement ms) { - if (ContextHolder.getRewrite()) { - return; - } - // 无重写,进行添加 - mappedStatementCache.addNoRewritable(ms, ContextHolder.getRules()); - } - - /** - * SQL 解析上下文,方便透传 {@link DataPermissionRule} 规则 - * - * @author iailab - */ - static final class ContextHolder { - - /** - * 该 {@link MappedStatement} 对应的规则 - */ - private static final ThreadLocal<List<DataPermissionRule>> RULES = ThreadLocal.withInitial(Collections::emptyList); - /** - * SQL 是否进行重写 - */ - private static final ThreadLocal<Boolean> REWRITE = ThreadLocal.withInitial(() -> Boolean.FALSE); - - public static void init(List<DataPermissionRule> rules) { - RULES.set(rules); - REWRITE.set(false); - } - - public static void clear() { - RULES.remove(); - REWRITE.remove(); - } - - public static boolean getRewrite() { - return REWRITE.get(); - } - - public static void setRewrite(boolean rewrite) { - REWRITE.set(rewrite); - } - - public static List<DataPermissionRule> getRules() { - return RULES.get(); - } - - } - - /** - * {@link MappedStatement} 缓存 - * 目前主要用于,记录 {@link DataPermissionRule} 是否对指定 {@link MappedStatement} 无效 - * 如果无效,则可以避免 SQL 的解析,加快速度 - * - * @author iailab - */ - static final class MappedStatementCache { - - /** - * 指定数据权限规则,对指定 MappedStatement 无需重写(不生效)的缓存 - * - * value:{@link MappedStatement#getId()} 编号 - */ - @Getter - private final Map<Class<? extends DataPermissionRule>, Set<String>> noRewritableMappedStatements = new ConcurrentHashMap<>(); - - /** - * 判断是否无需重写 - * ps:虽然有点中文式英语,但是容易读懂即可 - * - * @param ms MappedStatement - * @param rules 数据权限规则数组 - * @return 是否无需重写 - */ - public boolean noRewritable(MappedStatement ms, List<DataPermissionRule> rules) { - // 如果规则为空,说明无需重写 - if (CollUtil.isEmpty(rules)) { - return true; - } - // 任一规则不在 noRewritableMap 中,则说明可能需要重写 - for (DataPermissionRule rule : rules) { - Set<String> mappedStatementIds = noRewritableMappedStatements.get(rule.getClass()); - if (!CollUtil.contains(mappedStatementIds, ms.getId())) { - return false; - } - } - return true; - } - - /** - * 添加无需重写的 MappedStatement - * - * @param ms MappedStatement - * @param rules 数据权限规则数组 - */ - public void addNoRewritable(MappedStatement ms, List<DataPermissionRule> rules) { - for (DataPermissionRule rule : rules) { - Set<String> mappedStatementIds = noRewritableMappedStatements.get(rule.getClass()); - if (CollUtil.isNotEmpty(mappedStatementIds)) { - mappedStatementIds.add(ms.getId()); - } else { - noRewritableMappedStatements.put(rule.getClass(), SetUtils.asSet(ms.getId())); - } - } - } - - /** - * 清空缓存 - * 目前主要提供给单元测试 - */ - public void clear() { - noRewritableMappedStatements.clear(); - } - - } - -} diff --git a/iailab-framework/iailab-common-biz-data-permission/src/test/java/com/iailab/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest.java b/iailab-framework/iailab-common-biz-data-permission/src/test/java/com/iailab/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest.java deleted file mode 100644 index 72c2cff..0000000 --- a/iailab-framework/iailab-common-biz-data-permission/src/test/java/com/iailab/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest.java +++ /dev/null @@ -1,190 +0,0 @@ -package com.iailab.framework.datapermission.core.db; - -import com.iailab.framework.common.util.collection.SetUtils; -import com.iailab.framework.datapermission.core.rule.DataPermissionRule; -import com.iailab.framework.datapermission.core.rule.DataPermissionRuleFactory; -import com.iailab.framework.mybatis.core.util.MyBatisUtils; -import com.iailab.framework.test.core.ut.BaseMockitoUnitTest; -import com.baomidou.mybatisplus.core.toolkit.PluginUtils; -import net.sf.jsqlparser.expression.Alias; -import net.sf.jsqlparser.expression.Expression; -import net.sf.jsqlparser.expression.LongValue; -import net.sf.jsqlparser.expression.operators.relational.EqualsTo; -import net.sf.jsqlparser.schema.Column; -import org.apache.ibatis.executor.Executor; -import org.apache.ibatis.executor.statement.StatementHandler; -import org.apache.ibatis.mapping.BoundSql; -import org.apache.ibatis.mapping.MappedStatement; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockedStatic; - -import java.sql.Connection; -import java.util.*; - -import static java.util.Collections.singletonList; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; - -/** - * {@link DataPermissionDatabaseInterceptor} 的单元测试 - * 主要测试 {@link DataPermissionDatabaseInterceptor#beforePrepare(StatementHandler, Connection, Integer)} - * 和 {@link DataPermissionDatabaseInterceptor#beforeUpdate(Executor, MappedStatement, Object)} - * 以及在这个过程中,ContextHolder 和 MappedStatementCache - * - * @author iailab - */ -public class DataPermissionDatabaseInterceptorTest extends BaseMockitoUnitTest { - - @InjectMocks - private DataPermissionDatabaseInterceptor interceptor; - - @Mock - private DataPermissionRuleFactory ruleFactory; - - @BeforeEach - public void setUp() { - // 清理上下文 - DataPermissionDatabaseInterceptor.ContextHolder.clear(); - // 清空缓存 - interceptor.getMappedStatementCache().clear(); - } - - @Test // 不存在规则,且不匹配 - public void testBeforeQuery_withoutRule() { - try (MockedStatic<PluginUtils> pluginUtilsMock = mockStatic(PluginUtils.class)) { - // 准备参数 - MappedStatement mappedStatement = mock(MappedStatement.class); - BoundSql boundSql = mock(BoundSql.class); - - // 调用 - interceptor.beforeQuery(null, mappedStatement, null, null, null, boundSql); - // 断言 - pluginUtilsMock.verify(() -> PluginUtils.mpBoundSql(boundSql), never()); - } - } - - @Test // 存在规则,且不匹配 - public void testBeforeQuery_withMatchRule() { - try (MockedStatic<PluginUtils> pluginUtilsMock = mockStatic(PluginUtils.class)) { - // 准备参数 - MappedStatement mappedStatement = mock(MappedStatement.class); - BoundSql boundSql = mock(BoundSql.class); - // mock 方法(数据权限) - when(ruleFactory.getDataPermissionRule(same(mappedStatement.getId()))) - .thenReturn(singletonList(new DeptDataPermissionRule())); - // mock 方法(MPBoundSql) - PluginUtils.MPBoundSql mpBs = mock(PluginUtils.MPBoundSql.class); - pluginUtilsMock.when(() -> PluginUtils.mpBoundSql(same(boundSql))).thenReturn(mpBs); - // mock 方法(SQL) - String sql = "select * from t_user where id = 1"; - when(mpBs.sql()).thenReturn(sql); - // 针对 ContextHolder 和 MappedStatementCache 暂时不 mock,主要想校验过程中,数据是否正确 - - // 调用 - interceptor.beforeQuery(null, mappedStatement, null, null, null, boundSql); - // 断言 - verify(mpBs, times(1)).sql( - eq("SELECT * FROM t_user WHERE id = 1 AND t_user.dept_id = 100")); - // 断言缓存 - assertTrue(interceptor.getMappedStatementCache().getNoRewritableMappedStatements().isEmpty()); - } - } - - @Test // 存在规则,但不匹配 - public void testBeforeQuery_withoutMatchRule() { - try (MockedStatic<PluginUtils> pluginUtilsMock = mockStatic(PluginUtils.class)) { - // 准备参数 - MappedStatement mappedStatement = mock(MappedStatement.class); - BoundSql boundSql = mock(BoundSql.class); - // mock 方法(数据权限) - when(ruleFactory.getDataPermissionRule(same(mappedStatement.getId()))) - .thenReturn(singletonList(new DeptDataPermissionRule())); - // mock 方法(MPBoundSql) - PluginUtils.MPBoundSql mpBs = mock(PluginUtils.MPBoundSql.class); - pluginUtilsMock.when(() -> PluginUtils.mpBoundSql(same(boundSql))).thenReturn(mpBs); - // mock 方法(SQL) - String sql = "select * from t_role where id = 1"; - when(mpBs.sql()).thenReturn(sql); - // 针对 ContextHolder 和 MappedStatementCache 暂时不 mock,主要想校验过程中,数据是否正确 - - // 调用 - interceptor.beforeQuery(null, mappedStatement, null, null, null, boundSql); - // 断言 - verify(mpBs, times(1)).sql( - eq("SELECT * FROM t_role WHERE id = 1")); - // 断言缓存 - assertFalse(interceptor.getMappedStatementCache().getNoRewritableMappedStatements().isEmpty()); - } - } - - @Test - public void testAddNoRewritable() { - // 准备参数 - MappedStatement ms = mock(MappedStatement.class); - List<DataPermissionRule> rules = singletonList(new DeptDataPermissionRule()); - // mock 方法 - when(ms.getId()).thenReturn("selectById"); - - // 调用 - interceptor.getMappedStatementCache().addNoRewritable(ms, rules); - // 断言 - Map<Class<? extends DataPermissionRule>, Set<String>> noRewritableMappedStatements = - interceptor.getMappedStatementCache().getNoRewritableMappedStatements(); - assertEquals(1, noRewritableMappedStatements.size()); - assertEquals(SetUtils.asSet("selectById"), noRewritableMappedStatements.get(DeptDataPermissionRule.class)); - } - - @Test - public void testNoRewritable() { - // 准备参数 - MappedStatement ms = mock(MappedStatement.class); - // mock 方法 - when(ms.getId()).thenReturn("selectById"); - // mock 数据 - List<DataPermissionRule> rules = singletonList(new DeptDataPermissionRule()); - interceptor.getMappedStatementCache().addNoRewritable(ms, rules); - - // 场景一,rules 为空 - assertTrue(interceptor.getMappedStatementCache().noRewritable(ms, null)); - // 场景二,rules 非空,可重写 - assertFalse(interceptor.getMappedStatementCache().noRewritable(ms, singletonList(new EmptyDataPermissionRule()))); - // 场景三,rule 非空,不可重写 - assertTrue(interceptor.getMappedStatementCache().noRewritable(ms, rules)); - } - - private static class DeptDataPermissionRule implements DataPermissionRule { - - private static final String COLUMN = "dept_id"; - - @Override - public Set<String> getTableNames() { - return SetUtils.asSet("t_user"); - } - - @Override - public Expression getExpression(String tableName, Alias tableAlias) { - Column column = MyBatisUtils.buildColumn(tableName, tableAlias, COLUMN); - LongValue value = new LongValue(100L); - return new EqualsTo(column, value); - } - - } - - private static class EmptyDataPermissionRule implements DataPermissionRule { - - @Override - public Set<String> getTableNames() { - return Collections.emptySet(); - } - - @Override - public Expression getExpression(String tableName, Alias tableAlias) { - return null; - } - - } - -} diff --git a/iailab-framework/iailab-common-biz-data-permission/src/test/java/com/iailab/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest2.java b/iailab-framework/iailab-common-biz-data-permission/src/test/java/com/iailab/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest2.java deleted file mode 100644 index 5494508..0000000 --- a/iailab-framework/iailab-common-biz-data-permission/src/test/java/com/iailab/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest2.java +++ /dev/null @@ -1,533 +0,0 @@ -package com.iailab.framework.datapermission.core.db; - -import com.iailab.framework.datapermission.core.rule.DataPermissionRule; -import com.iailab.framework.datapermission.core.rule.DataPermissionRuleFactory; -import com.iailab.framework.mybatis.core.util.MyBatisUtils; -import com.iailab.framework.test.core.ut.BaseMockitoUnitTest; -import net.sf.jsqlparser.expression.Alias; -import net.sf.jsqlparser.expression.Expression; -import net.sf.jsqlparser.expression.LongValue; -import net.sf.jsqlparser.expression.operators.relational.EqualsTo; -import net.sf.jsqlparser.expression.operators.relational.ExpressionList; -import net.sf.jsqlparser.expression.operators.relational.InExpression; -import net.sf.jsqlparser.schema.Column; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; - -import java.util.Arrays; -import java.util.Set; - -import static com.iailab.framework.common.util.collection.SetUtils.asSet; -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * {@link DataPermissionDatabaseInterceptor} 的单元测试 - * 主要复用了 MyBatis Plus 的 TenantLineInnerInterceptorTest 的单元测试 - * 不过它的单元测试不是很规范,考虑到是复用的,所以暂时不进行修改~ - * - * @author iailab - */ -public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest { - - @InjectMocks - private DataPermissionDatabaseInterceptor interceptor; - - @Mock - private DataPermissionRuleFactory ruleFactory; - - @BeforeEach - public void setUp() { - // 租户的数据权限规则 - DataPermissionRule tenantRule = new DataPermissionRule() { - - private static final String COLUMN = "tenant_id"; - - @Override - public Set<String> getTableNames() { - return asSet("entity", "entity1", "entity2", "entity3", "t1", "t2", "sys_dict_item", // 支持 MyBatis Plus 的单元测试 - "t_user", "t_role"); // 满足自己的单元测试 - } - - @Override - public Expression getExpression(String tableName, Alias tableAlias) { - Column column = MyBatisUtils.buildColumn(tableName, tableAlias, COLUMN); - LongValue value = new LongValue(1L); - return new EqualsTo(column, value); - } - - }; - // 部门的数据权限规则 - DataPermissionRule deptRule = new DataPermissionRule() { - - private static final String COLUMN = "dept_id"; - - @Override - public Set<String> getTableNames() { - return asSet("t_user"); // 满足自己的单元测试 - } - - @Override - public Expression getExpression(String tableName, Alias tableAlias) { - Column column = MyBatisUtils.buildColumn(tableName, tableAlias, COLUMN); - ExpressionList values = new ExpressionList(new LongValue(10L), - new LongValue(20L)); - return new InExpression(column, values); - } - - }; - // 设置到上下文,保证 - DataPermissionDatabaseInterceptor.ContextHolder.init(Arrays.asList(tenantRule, deptRule)); - } - - @Test - void delete() { - assertSql("delete from entity where id = ?", - "DELETE FROM entity WHERE id = ? AND entity.tenant_id = 1"); - } - - @Test - void update() { - assertSql("update entity set name = ? where id = ?", - "UPDATE entity SET name = ? WHERE id = ? AND entity.tenant_id = 1"); - } - - @Test - void selectSingle() { - // 单表 - assertSql("select * from entity where id = ?", - "SELECT * FROM entity WHERE id = ? AND entity.tenant_id = 1"); - - assertSql("select * from entity where id = ? or name = ?", - "SELECT * FROM entity WHERE (id = ? OR name = ?) AND entity.tenant_id = 1"); - - assertSql("SELECT * FROM entity WHERE (id = ? OR name = ?)", - "SELECT * FROM entity WHERE (id = ? OR name = ?) AND entity.tenant_id = 1"); - - /* not */ - assertSql("SELECT * FROM entity WHERE not (id = ? OR name = ?)", - "SELECT * FROM entity WHERE NOT (id = ? OR name = ?) AND entity.tenant_id = 1"); - } - - @Test - void selectSubSelectIn() { - /* in */ - assertSql("SELECT * FROM entity e WHERE e.id IN (select e1.id from entity1 e1 where e1.id = ?)", - "SELECT * FROM entity e WHERE e.id IN (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); - // 在最前 - assertSql("SELECT * FROM entity e WHERE e.id IN " + - "(select e1.id from entity1 e1 where e1.id = ?) and e.id = ?", - "SELECT * FROM entity e WHERE e.id IN " + - "(SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.id = ? AND e.tenant_id = 1"); - // 在最后 - assertSql("SELECT * FROM entity e WHERE e.id = ? and e.id IN " + - "(select e1.id from entity1 e1 where e1.id = ?)", - "SELECT * FROM entity e WHERE e.id = ? AND e.id IN " + - "(SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); - // 在中间 - assertSql("SELECT * FROM entity e WHERE e.id = ? and e.id IN " + - "(select e1.id from entity1 e1 where e1.id = ?) and e.id = ?", - "SELECT * FROM entity e WHERE e.id = ? AND e.id IN " + - "(SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.id = ? AND e.tenant_id = 1"); - } - - @Test - void selectSubSelectEq() { - /* = */ - assertSql("SELECT * FROM entity e WHERE e.id = (select e1.id from entity1 e1 where e1.id = ?)", - "SELECT * FROM entity e WHERE e.id = (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); - } - - @Test - void selectSubSelectInnerNotEq() { - /* inner not = */ - assertSql("SELECT * FROM entity e WHERE not (e.id = (select e1.id from entity1 e1 where e1.id = ?))", - "SELECT * FROM entity e WHERE NOT (e.id = (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1)) AND e.tenant_id = 1"); - - assertSql("SELECT * FROM entity e WHERE not (e.id = (select e1.id from entity1 e1 where e1.id = ?) and e.id = ?)", - "SELECT * FROM entity e WHERE NOT (e.id = (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.id = ?) AND e.tenant_id = 1"); - } - - @Test - void selectSubSelectExists() { - /* EXISTS */ - assertSql("SELECT * FROM entity e WHERE EXISTS (select e1.id from entity1 e1 where e1.id = ?)", - "SELECT * FROM entity e WHERE EXISTS (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); - - - /* NOT EXISTS */ - assertSql("SELECT * FROM entity e WHERE NOT EXISTS (select e1.id from entity1 e1 where e1.id = ?)", - "SELECT * FROM entity e WHERE NOT EXISTS (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); - } - - @Test - void selectSubSelect() { - /* >= */ - assertSql("SELECT * FROM entity e WHERE e.id >= (select e1.id from entity1 e1 where e1.id = ?)", - "SELECT * FROM entity e WHERE e.id >= (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); - - - /* <= */ - assertSql("SELECT * FROM entity e WHERE e.id <= (select e1.id from entity1 e1 where e1.id = ?)", - "SELECT * FROM entity e WHERE e.id <= (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); - - - /* <> */ - assertSql("SELECT * FROM entity e WHERE e.id <> (select e1.id from entity1 e1 where e1.id = ?)", - "SELECT * FROM entity e WHERE e.id <> (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); - } - - @Test - void selectFromSelect() { - assertSql("SELECT * FROM (select e.id from entity e WHERE e.id = (select e1.id from entity1 e1 where e1.id = ?))", - "SELECT * FROM (SELECT e.id FROM entity e WHERE e.id = (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1)"); - } - - @Test - void selectBodySubSelect() { - assertSql("select t1.col1,(select t2.col2 from t2 t2 where t1.col1=t2.col1) from t1 t1", - "SELECT t1.col1, (SELECT t2.col2 FROM t2 t2 WHERE t1.col1 = t2.col1 AND t2.tenant_id = 1) FROM t1 t1 WHERE t1.tenant_id = 1"); - } - - @Test - void selectLeftJoin() { - // left join - assertSql("SELECT * FROM entity e " + - "left join entity1 e1 on e1.id = e.id " + - "WHERE e.id = ? OR e.name = ?", - "SELECT * FROM entity e " + - "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + - "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1"); - - assertSql("SELECT * FROM entity e " + - "left join entity1 e1 on e1.id = e.id " + - "WHERE (e.id = ? OR e.name = ?)", - "SELECT * FROM entity e " + - "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + - "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1"); - - assertSql("SELECT * FROM entity e " + - "left join entity1 e1 on e1.id = e.id " + - "left join entity2 e2 on e1.id = e2.id", - "SELECT * FROM entity e " + - "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + - "LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1 " + - "WHERE e.tenant_id = 1"); - } - - @Test - void selectRightJoin() { - // right join - assertSql("SELECT * FROM entity e " + - "right join entity1 e1 on e1.id = e.id", - "SELECT * FROM entity e " + - "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " + - "WHERE e1.tenant_id = 1"); - - assertSql("SELECT * FROM with_as_1 e " + - "right join entity1 e1 on e1.id = e.id", - "SELECT * FROM with_as_1 e " + - "RIGHT JOIN entity1 e1 ON e1.id = e.id " + - "WHERE e1.tenant_id = 1"); - - assertSql("SELECT * FROM entity e " + - "right join entity1 e1 on e1.id = e.id " + - "WHERE e.id = ? OR e.name = ?", - "SELECT * FROM entity e " + - "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " + - "WHERE (e.id = ? OR e.name = ?) AND e1.tenant_id = 1"); - - assertSql("SELECT * FROM entity e " + - "right join entity1 e1 on e1.id = e.id " + - "right join entity2 e2 on e1.id = e2.id ", - "SELECT * FROM entity e " + - "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " + - "RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1 " + - "WHERE e2.tenant_id = 1"); - } - - @Test - void selectMixJoin() { - assertSql("SELECT * FROM entity e " + - "right join entity1 e1 on e1.id = e.id " + - "left join entity2 e2 on e1.id = e2.id", - "SELECT * FROM entity e " + - "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " + - "LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1 " + - "WHERE e1.tenant_id = 1"); - - assertSql("SELECT * FROM entity e " + - "left join entity1 e1 on e1.id = e.id " + - "right join entity2 e2 on e1.id = e2.id", - "SELECT * FROM entity e " + - "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + - "RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1 " + - "WHERE e2.tenant_id = 1"); - - assertSql("SELECT * FROM entity e " + - "left join entity1 e1 on e1.id = e.id " + - "inner join entity2 e2 on e1.id = e2.id", - "SELECT * FROM entity e " + - "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + - "INNER JOIN entity2 e2 ON e1.id = e2.id AND e.tenant_id = 1 AND e2.tenant_id = 1"); - } - - - @Test - void selectJoinSubSelect() { - assertSql("select * from (select * from entity) e1 " + - "left join entity2 e2 on e1.id = e2.id", - "SELECT * FROM (SELECT * FROM entity WHERE entity.tenant_id = 1) e1 " + - "LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1"); - - assertSql("select * from entity1 e1 " + - "left join (select * from entity2) e2 " + - "on e1.id = e2.id", - "SELECT * FROM entity1 e1 " + - "LEFT JOIN (SELECT * FROM entity2 WHERE entity2.tenant_id = 1) e2 " + - "ON e1.id = e2.id " + - "WHERE e1.tenant_id = 1"); - } - - @Test - void selectSubJoin() { - - assertSql("select * FROM " + - "(entity1 e1 right JOIN entity2 e2 ON e1.id = e2.id)", - "SELECT * FROM " + - "(entity1 e1 RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1) " + - "WHERE e2.tenant_id = 1"); - - assertSql("select * FROM " + - "(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id)", - "SELECT * FROM " + - "(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " + - "WHERE e1.tenant_id = 1"); - - - assertSql("select * FROM " + - "(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id) " + - "right join entity3 e3 on e1.id = e3.id", - "SELECT * FROM " + - "(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " + - "RIGHT JOIN entity3 e3 ON e1.id = e3.id AND e1.tenant_id = 1 " + - "WHERE e3.tenant_id = 1"); - - - assertSql("select * FROM entity e " + - "LEFT JOIN (entity1 e1 right join entity2 e2 ON e1.id = e2.id) " + - "on e.id = e2.id", - "SELECT * FROM entity e " + - "LEFT JOIN (entity1 e1 RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1) " + - "ON e.id = e2.id AND e2.tenant_id = 1 " + - "WHERE e.tenant_id = 1"); - - assertSql("select * FROM entity e " + - "LEFT JOIN (entity1 e1 left join entity2 e2 ON e1.id = e2.id) " + - "on e.id = e2.id", - "SELECT * FROM entity e " + - "LEFT JOIN (entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " + - "ON e.id = e2.id AND e1.tenant_id = 1 " + - "WHERE e.tenant_id = 1"); - - assertSql("select * FROM entity e " + - "RIGHT JOIN (entity1 e1 left join entity2 e2 ON e1.id = e2.id) " + - "on e.id = e2.id", - "SELECT * FROM entity e " + - "RIGHT JOIN (entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " + - "ON e.id = e2.id AND e.tenant_id = 1 " + - "WHERE e1.tenant_id = 1"); - } - - - @Test - void selectLeftJoinMultipleTrailingOn() { - // 多个 on 尾缀的 - assertSql("SELECT * FROM entity e " + - "LEFT JOIN entity1 e1 " + - "LEFT JOIN entity2 e2 ON e2.id = e1.id " + - "ON e1.id = e.id " + - "WHERE (e.id = ? OR e.NAME = ?)", - "SELECT * FROM entity e " + - "LEFT JOIN entity1 e1 " + - "LEFT JOIN entity2 e2 ON e2.id = e1.id AND e2.tenant_id = 1 " + - "ON e1.id = e.id AND e1.tenant_id = 1 " + - "WHERE (e.id = ? OR e.NAME = ?) AND e.tenant_id = 1"); - - assertSql("SELECT * FROM entity e " + - "LEFT JOIN entity1 e1 " + - "LEFT JOIN with_as_A e2 ON e2.id = e1.id " + - "ON e1.id = e.id " + - "WHERE (e.id = ? OR e.NAME = ?)", - "SELECT * FROM entity e " + - "LEFT JOIN entity1 e1 " + - "LEFT JOIN with_as_A e2 ON e2.id = e1.id " + - "ON e1.id = e.id AND e1.tenant_id = 1 " + - "WHERE (e.id = ? OR e.NAME = ?) AND e.tenant_id = 1"); - } - - @Test - void selectInnerJoin() { - // inner join - assertSql("SELECT * FROM entity e " + - "inner join entity1 e1 on e1.id = e.id " + - "WHERE e.id = ? OR e.name = ?", - "SELECT * FROM entity e " + - "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e1.tenant_id = 1 " + - "WHERE e.id = ? OR e.name = ?"); - - assertSql("SELECT * FROM entity e " + - "inner join entity1 e1 on e1.id = e.id " + - "WHERE (e.id = ? OR e.name = ?)", - "SELECT * FROM entity e " + - "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e1.tenant_id = 1 " + - "WHERE (e.id = ? OR e.name = ?)"); - - // 隐式内连接 - assertSql("SELECT * FROM entity,entity1 " + - "WHERE entity.id = entity1.id", - "SELECT * FROM entity, entity1 " + - "WHERE entity.id = entity1.id AND entity.tenant_id = 1 AND entity1.tenant_id = 1"); - - // 隐式内连接 - assertSql("SELECT * FROM entity a, with_as_entity1 b " + - "WHERE a.id = b.id", - "SELECT * FROM entity a, with_as_entity1 b " + - "WHERE a.id = b.id AND a.tenant_id = 1"); - - assertSql("SELECT * FROM with_as_entity a, with_as_entity1 b " + - "WHERE a.id = b.id", - "SELECT * FROM with_as_entity a, with_as_entity1 b " + - "WHERE a.id = b.id"); - - // SubJoin with 隐式内连接 - assertSql("SELECT * FROM (entity,entity1) " + - "WHERE entity.id = entity1.id", - "SELECT * FROM (entity, entity1) " + - "WHERE entity.id = entity1.id " + - "AND entity.tenant_id = 1 AND entity1.tenant_id = 1"); - - assertSql("SELECT * FROM ((entity,entity1),entity2) " + - "WHERE entity.id = entity1.id and entity.id = entity2.id", - "SELECT * FROM ((entity, entity1), entity2) " + - "WHERE entity.id = entity1.id AND entity.id = entity2.id " + - "AND entity.tenant_id = 1 AND entity1.tenant_id = 1 AND entity2.tenant_id = 1"); - - assertSql("SELECT * FROM (entity,(entity1,entity2)) " + - "WHERE entity.id = entity1.id and entity.id = entity2.id", - "SELECT * FROM (entity, (entity1, entity2)) " + - "WHERE entity.id = entity1.id AND entity.id = entity2.id " + - "AND entity.tenant_id = 1 AND entity1.tenant_id = 1 AND entity2.tenant_id = 1"); - - // 沙雕的括号写法 - assertSql("SELECT * FROM (((entity,entity1))) " + - "WHERE entity.id = entity1.id", - "SELECT * FROM (((entity, entity1))) " + - "WHERE entity.id = entity1.id " + - "AND entity.tenant_id = 1 AND entity1.tenant_id = 1"); - - } - - - @Test - void selectWithAs() { - assertSql("with with_as_A as (select * from entity) select * from with_as_A", - "WITH with_as_A AS (SELECT * FROM entity WHERE entity.tenant_id = 1) SELECT * FROM with_as_A"); - } - - - @Test - void selectIgnoreTable() { - assertSql(" SELECT dict.dict_code, item.item_text AS \"text\", item.item_value AS \"value\" FROM sys_dict_item item INNER JOIN sys_dict dict ON dict.id = item.dict_id WHERE dict.dict_code IN (1, 2, 3) AND item.item_value IN (1, 2, 3)", - "SELECT dict.dict_code, item.item_text AS \"text\", item.item_value AS \"value\" FROM sys_dict_item item INNER JOIN sys_dict dict ON dict.id = item.dict_id AND item.tenant_id = 1 WHERE dict.dict_code IN (1, 2, 3) AND item.item_value IN (1, 2, 3)"); - } - - private void assertSql(String sql, String targetSql) { - assertEquals(targetSql, interceptor.parserSingle(sql, null)); - } - - - // ========== 额外的测试 ========== - - @Test - public void testSelectSingle() { - // 单表 - assertSql("select * from t_user where id = ?", - "SELECT * FROM t_user WHERE id = ? AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)"); - - assertSql("select * from t_user where id = ? or name = ?", - "SELECT * FROM t_user WHERE (id = ? OR name = ?) AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)"); - - assertSql("SELECT * FROM t_user WHERE (id = ? OR name = ?)", - "SELECT * FROM t_user WHERE (id = ? OR name = ?) AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)"); - - /* not */ - assertSql("SELECT * FROM t_user WHERE not (id = ? OR name = ?)", - "SELECT * FROM t_user WHERE NOT (id = ? OR name = ?) AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)"); - } - - @Test - public void testSelectLeftJoin() { - // left join - assertSql("SELECT * FROM t_user e " + - "left join t_role e1 on e1.id = e.id " + - "WHERE e.id = ? OR e.name = ?", - "SELECT * FROM t_user e " + - "LEFT JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " + - "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)"); - - // 条件 e.id = ? OR e.name = ? 带括号 - assertSql("SELECT * FROM t_user e " + - "left join t_role e1 on e1.id = e.id " + - "WHERE (e.id = ? OR e.name = ?)", - "SELECT * FROM t_user e " + - "LEFT JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " + - "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)"); - } - - @Test - public void testSelectRightJoin() { - // right join - assertSql("SELECT * FROM t_user e " + - "right join t_role e1 on e1.id = e.id " + - "WHERE e.id = ? OR e.name = ?", - "SELECT * FROM t_user e " + - "RIGHT JOIN t_role e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) " + - "WHERE (e.id = ? OR e.name = ?) AND e1.tenant_id = 1"); - - // 条件 e.id = ? OR e.name = ? 带括号 - assertSql("SELECT * FROM t_user e " + - "right join t_role e1 on e1.id = e.id " + - "WHERE (e.id = ? OR e.name = ?)", - "SELECT * FROM t_user e " + - "RIGHT JOIN t_role e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) " + - "WHERE (e.id = ? OR e.name = ?) AND e1.tenant_id = 1"); - } - - @Test - public void testSelectInnerJoin() { - // inner join - assertSql("SELECT * FROM t_user e " + - "inner join entity1 e1 on e1.id = e.id " + - "WHERE e.id = ? OR e.name = ?", - "SELECT * FROM t_user e " + - "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) AND e1.tenant_id = 1 " + - "WHERE e.id = ? OR e.name = ?"); - - // 条件 e.id = ? OR e.name = ? 带括号 - assertSql("SELECT * FROM t_user e " + - "inner join entity1 e1 on e1.id = e.id " + - "WHERE (e.id = ? OR e.name = ?)", - "SELECT * FROM t_user e " + - "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) AND e1.tenant_id = 1 " + - "WHERE (e.id = ? OR e.name = ?)"); - - // 没有 On 的 inner join - assertSql("SELECT * FROM entity,entity1 " + - "WHERE entity.id = entity1.id", - "SELECT * FROM entity, entity1 " + - "WHERE entity.id = entity1.id AND entity.tenant_id = 1 AND entity1.tenant_id = 1"); - } - -} -- Gitblit v1.9.3