Commit 0f792c64e7bcbcc7bf601ff696b99f310aa11268

Authored by YunaiV
1 parent e9385219

通过 MyBatis Plus 数据权限的单测

yudao-framework/yudao-spring-boot-starter-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/interceptor/DataPermissionInterceptor.java
@@ -330,6 +330,7 @@ public class DataPermissionInterceptor extends JsqlParserSupport implements Inne @@ -330,6 +330,7 @@ public class DataPermissionInterceptor extends JsqlParserSupport implements Inne
330 // boolean needIgnore = ignoreTable(fromTable.getName()); 330 // boolean needIgnore = ignoreTable(fromTable.getName());
331 // // 表名压栈,忽略的表压入 null,以便后续不处理 331 // // 表名压栈,忽略的表压入 null,以便后续不处理
332 // tables.push(needIgnore ? null : fromTable); 332 // tables.push(needIgnore ? null : fromTable);
  333 + tables.push(fromTable);
333 // 尾缀多个 on 表达式的时候统一处理 334 // 尾缀多个 on 表达式的时候统一处理
334 if (originOnExpressions.size() > 1) { 335 if (originOnExpressions.size() > 1) {
335 Collection<Expression> onExpressions = new LinkedList<>(); 336 Collection<Expression> onExpressions = new LinkedList<>();
@@ -457,7 +458,7 @@ public class DataPermissionInterceptor extends JsqlParserSupport implements Inne @@ -457,7 +458,7 @@ public class DataPermissionInterceptor extends JsqlParserSupport implements Inne
457 * 458 *
458 * @author 芋道源码 459 * @author 芋道源码
459 */ 460 */
460 - private static final class ContextHolder { 461 + static final class ContextHolder {
461 462
462 /** 463 /**
463 * 该 {@link MappedStatement} 对应的规则 464 * 该 {@link MappedStatement} 对应的规则
yudao-framework/yudao-spring-boot-starter-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/interceptor/DataPermissionInterceptorTest.java deleted
1 -package cn.iocoder.yudao.framework.datapermission.core.interceptor;  
2 -  
3 -import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRuleFactory;  
4 -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;  
5 -import org.junit.jupiter.api.Test;  
6 -import org.mockito.InjectMocks;  
7 -import org.mockito.Mock;  
8 -  
9 -import static org.assertj.core.api.Assertions.assertThat;  
10 -  
11 -public class DataPermissionInterceptorTest extends BaseMockitoUnitTest {  
12 -  
13 - @InjectMocks  
14 - private DataPermissionInterceptor interceptor;  
15 -  
16 - @Mock  
17 - private DataPermissionRuleFactory ruleFactory;  
18 -  
19 - @Test  
20 - public void selectSingle() {  
21 - // 单表  
22 - assertSql("select * from entity where id = ?",  
23 - "SELECT * FROM entity WHERE id = ? AND tenant_id = 1");  
24 -  
25 - assertSql("select * from entity where id = ? or name = ?",  
26 - "SELECT * FROM entity WHERE (id = ? OR name = ?) AND tenant_id = 1");  
27 -  
28 - assertSql("SELECT * FROM entity WHERE (id = ? OR name = ?)",  
29 - "SELECT * FROM entity WHERE (id = ? OR name = ?) AND tenant_id = 1");  
30 -  
31 - /* not */  
32 - assertSql("SELECT * FROM entity WHERE not (id = ? OR name = ?)",  
33 - "SELECT * FROM entity WHERE NOT (id = ? OR name = ?) AND tenant_id = 1");  
34 - }  
35 -  
36 - private void assertSql(String sql, String targetSql) {  
37 - assertThat(interceptor.parserSingle(sql, null)).isEqualTo(targetSql);  
38 - }  
39 -  
40 - public static void main(String[] args) {  
41 - System.out.println("123");  
42 - }  
43 -  
44 -}  
yudao-framework/yudao-spring-boot-starter-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/interceptor/DataPermissionInterceptorTest2.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.datapermission.core.interceptor;
  2 +
  3 +import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule;
  4 +import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRuleFactory;
  5 +import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
  6 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  7 +import net.sf.jsqlparser.expression.Alias;
  8 +import net.sf.jsqlparser.expression.Expression;
  9 +import net.sf.jsqlparser.expression.LongValue;
  10 +import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
  11 +import net.sf.jsqlparser.schema.Column;
  12 +import org.junit.jupiter.api.BeforeEach;
  13 +import org.junit.jupiter.api.Test;
  14 +import org.mockito.InjectMocks;
  15 +import org.mockito.Mock;
  16 +
  17 +import java.util.Collections;
  18 +import java.util.Set;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
  21 +import static org.junit.jupiter.api.Assertions.assertEquals;
  22 +
  23 +/**
  24 + * {@link DataPermissionInterceptor} 的单元测试
  25 + * 主要复用了 MyBatis Plus 的 TenantLineInnerInterceptorTest 的单元测试
  26 + * 不过它的单元测试不是很规范,考虑到是复用的,所以暂时不进行修改~
  27 + *
  28 + * @author 芋道源码
  29 + */
  30 +public class DataPermissionInterceptorTest2 extends BaseMockitoUnitTest {
  31 +
  32 + @InjectMocks
  33 + private DataPermissionInterceptor interceptor;
  34 +
  35 + @Mock
  36 + private DataPermissionRuleFactory ruleFactory;
  37 +
  38 + @BeforeEach
  39 + public void setUp() {
  40 + // 租户的数据权限规则
  41 + DataPermissionRule tenantRule = new DataPermissionRule() {
  42 +
  43 + private static final String COLUMN = "tenant_id";
  44 +
  45 + @Override
  46 + public Set<String> getTableNames() {
  47 + return asSet("entity", "entity1", "entity2", "t1", "t2");
  48 + }
  49 +
  50 + @Override
  51 + public Expression getExpression(String tableName, Alias tableAlias) {
  52 + Column column = MyBatisUtils.buildColumn(tableName, tableAlias, COLUMN);
  53 + LongValue value = new LongValue(1L);
  54 + return new EqualsTo(column, value);
  55 + }
  56 +
  57 + };
  58 + // 设置到上下文,保证
  59 + DataPermissionInterceptor.ContextHolder.init(Collections.singletonList(tenantRule));
  60 + }
  61 +
  62 + @Test
  63 + void delete() {
  64 + assertSql("delete from entity where id = ?",
  65 + "DELETE FROM entity WHERE id = ? AND tenant_id = 1");
  66 + }
  67 +
  68 + @Test
  69 + void update() {
  70 + assertSql("update entity set name = ? where id = ?",
  71 + "UPDATE entity SET name = ? WHERE id = ? AND tenant_id = 1");
  72 + }
  73 +
  74 + @Test
  75 + void selectSingle() {
  76 + // 单表
  77 + assertSql("select * from entity where id = ?",
  78 + "SELECT * FROM entity WHERE id = ? AND tenant_id = 1");
  79 +
  80 + assertSql("select * from entity where id = ? or name = ?",
  81 + "SELECT * FROM entity WHERE (id = ? OR name = ?) AND tenant_id = 1");
  82 +
  83 + assertSql("SELECT * FROM entity WHERE (id = ? OR name = ?)",
  84 + "SELECT * FROM entity WHERE (id = ? OR name = ?) AND tenant_id = 1");
  85 +
  86 + /* not */
  87 + assertSql("SELECT * FROM entity WHERE not (id = ? OR name = ?)",
  88 + "SELECT * FROM entity WHERE NOT (id = ? OR name = ?) AND tenant_id = 1");
  89 + }
  90 +
  91 + @Test
  92 + void selectSubSelectIn() {
  93 + /* in */
  94 + assertSql("SELECT * FROM entity e WHERE e.id IN (select e1.id from entity1 e1 where e1.id = ?)",
  95 + "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");
  96 + // 在最前
  97 + assertSql("SELECT * FROM entity e WHERE e.id IN " +
  98 + "(select e1.id from entity1 e1 where e1.id = ?) and e.id = ?",
  99 + "SELECT * FROM entity e WHERE e.id IN " +
  100 + "(SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.id = ? AND e.tenant_id = 1");
  101 + // 在最后
  102 + assertSql("SELECT * FROM entity e WHERE e.id = ? and e.id IN " +
  103 + "(select e1.id from entity1 e1 where e1.id = ?)",
  104 + "SELECT * FROM entity e WHERE e.id = ? AND e.id IN " +
  105 + "(SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1");
  106 + // 在中间
  107 + assertSql("SELECT * FROM entity e WHERE e.id = ? and e.id IN " +
  108 + "(select e1.id from entity1 e1 where e1.id = ?) and e.id = ?",
  109 + "SELECT * FROM entity e WHERE e.id = ? AND e.id IN " +
  110 + "(SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.id = ? AND e.tenant_id = 1");
  111 + }
  112 +
  113 + @Test
  114 + void selectSubSelectEq() {
  115 + /* = */
  116 + assertSql("SELECT * FROM entity e WHERE e.id = (select e1.id from entity1 e1 where e1.id = ?)",
  117 + "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");
  118 + }
  119 +
  120 + @Test
  121 + void selectSubSelectInnerNotEq() {
  122 + /* inner not = */
  123 + assertSql("SELECT * FROM entity e WHERE not (e.id = (select e1.id from entity1 e1 where e1.id = ?))",
  124 + "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");
  125 +
  126 + assertSql("SELECT * FROM entity e WHERE not (e.id = (select e1.id from entity1 e1 where e1.id = ?) and e.id = ?)",
  127 + "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");
  128 + }
  129 +
  130 + @Test
  131 + void selectSubSelectExists() {
  132 + /* EXISTS */
  133 + assertSql("SELECT * FROM entity e WHERE EXISTS (select e1.id from entity1 e1 where e1.id = ?)",
  134 + "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");
  135 +
  136 +
  137 + /* NOT EXISTS */
  138 + assertSql("SELECT * FROM entity e WHERE NOT EXISTS (select e1.id from entity1 e1 where e1.id = ?)",
  139 + "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");
  140 + }
  141 +
  142 + @Test
  143 + void selectSubSelect() {
  144 + /* >= */
  145 + assertSql("SELECT * FROM entity e WHERE e.id >= (select e1.id from entity1 e1 where e1.id = ?)",
  146 + "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");
  147 +
  148 + /* <= */
  149 + assertSql("SELECT * FROM entity e WHERE e.id <= (select e1.id from entity1 e1 where e1.id = ?)",
  150 + "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");
  151 +
  152 + /* <> */
  153 + assertSql("SELECT * FROM entity e WHERE e.id <> (select e1.id from entity1 e1 where e1.id = ?)",
  154 + "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");
  155 + }
  156 +
  157 + @Test
  158 + void selectFromSelect() {
  159 + assertSql("SELECT * FROM (select e.id from entity e WHERE e.id = (select e1.id from entity1 e1 where e1.id = ?))",
  160 + "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)");
  161 + }
  162 +
  163 + @Test
  164 + void selectBodySubSelect() {
  165 + assertSql("select t1.col1,(select t2.col2 from t2 t2 where t1.col1=t2.col1) from t1 t1",
  166 + "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");
  167 + }
  168 +
  169 + @Test
  170 + void selectLeftJoin() {
  171 + // left join
  172 + assertSql("SELECT * FROM entity e " +
  173 + "left join entity1 e1 on e1.id = e.id " +
  174 + "WHERE e.id = ? OR e.name = ?",
  175 + "SELECT * FROM entity e " +
  176 + "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
  177 + "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1");
  178 +
  179 + assertSql("SELECT * FROM entity e " +
  180 + "left join entity1 e1 on e1.id = e.id " +
  181 + "WHERE (e.id = ? OR e.name = ?)",
  182 + "SELECT * FROM entity e " +
  183 + "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
  184 + "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1");
  185 + }
  186 +
  187 + @Test
  188 + void selectRightJoin() {
  189 + // right join
  190 + assertSql("SELECT * FROM entity e " +
  191 + "right join entity1 e1 on e1.id = e.id",
  192 + "SELECT * FROM entity e " +
  193 + "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
  194 + "WHERE e.tenant_id = 1");
  195 +
  196 + assertSql("SELECT * FROM entity e " +
  197 + "right join entity1 e1 on e1.id = e.id " +
  198 + "WHERE e.id = ? OR e.name = ?",
  199 + "SELECT * FROM entity e " +
  200 + "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
  201 + "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1");
  202 + }
  203 +
  204 + @Test
  205 + void selectLeftJoinMultipleTrailingOn() {
  206 + // 多个 on 尾缀的
  207 + assertSql("SELECT * FROM entity e " +
  208 + "LEFT JOIN entity1 e1 " +
  209 + "LEFT JOIN entity2 e2 ON e2.id = e1.id " +
  210 + "ON e1.id = e.id " +
  211 + "WHERE (e.id = ? OR e.NAME = ?)",
  212 + "SELECT * FROM entity e " +
  213 + "LEFT JOIN entity1 e1 " +
  214 + "LEFT JOIN entity2 e2 ON e2.id = e1.id AND e2.tenant_id = 1 " +
  215 + "ON e1.id = e.id AND e1.tenant_id = 1 " +
  216 + "WHERE (e.id = ? OR e.NAME = ?) AND e.tenant_id = 1");
  217 +
  218 + assertSql("SELECT * FROM entity e " +
  219 + "LEFT JOIN entity1 e1 " +
  220 + "LEFT JOIN with_as_A e2 ON e2.id = e1.id " +
  221 + "ON e1.id = e.id " +
  222 + "WHERE (e.id = ? OR e.NAME = ?)",
  223 + "SELECT * FROM entity e " +
  224 + "LEFT JOIN entity1 e1 " +
  225 + "LEFT JOIN with_as_A e2 ON e2.id = e1.id " +
  226 + "ON e1.id = e.id AND e1.tenant_id = 1 " +
  227 + "WHERE (e.id = ? OR e.NAME = ?) AND e.tenant_id = 1");
  228 + }
  229 +
  230 + @Test
  231 + void selectInnerJoin() {
  232 + // inner join
  233 + assertSql("SELECT * FROM entity e " +
  234 + "inner join entity1 e1 on e1.id = e.id " +
  235 + "WHERE e.id = ? OR e.name = ?",
  236 + "SELECT * FROM entity e " +
  237 + "INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
  238 + "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1");
  239 +
  240 + assertSql("SELECT * FROM entity e " +
  241 + "inner join entity1 e1 on e1.id = e.id " +
  242 + "WHERE (e.id = ? OR e.name = ?)",
  243 + "SELECT * FROM entity e " +
  244 + "INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
  245 + "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1");
  246 +
  247 + // 垃圾 inner join todo
  248 +// assertSql("SELECT * FROM entity,entity1 " +
  249 +// "WHERE entity.id = entity1.id",
  250 +// "SELECT * FROM entity e " +
  251 +// "INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
  252 +// "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1");
  253 + }
  254 +
  255 +
  256 + @Test
  257 + void selectWithAs() {
  258 + assertSql("with with_as_A as (select * from entity) select * from with_as_A",
  259 + "WITH with_as_A AS (SELECT * FROM entity WHERE tenant_id = 1) SELECT * FROM with_as_A");
  260 + }
  261 +
  262 + private void assertSql(String sql, String targetSql) {
  263 + assertEquals(targetSql, interceptor.parserSingle(sql, null));
  264 + }
  265 +
  266 +}
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java
@@ -7,6 +7,8 @@ import com.baomidou.mybatisplus.core.metadata.OrderItem; @@ -7,6 +7,8 @@ import com.baomidou.mybatisplus.core.metadata.OrderItem;
7 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 7 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
8 import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; 8 import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
9 import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 9 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  10 +import net.sf.jsqlparser.expression.Alias;
  11 +import net.sf.jsqlparser.schema.Column;
10 import net.sf.jsqlparser.schema.Table; 12 import net.sf.jsqlparser.schema.Table;
11 13
12 import java.util.ArrayList; 14 import java.util.ArrayList;
@@ -67,4 +69,16 @@ public class MyBatisUtils { @@ -67,4 +69,16 @@ public class MyBatisUtils {
67 return tableName; 69 return tableName;
68 } 70 }
69 71
  72 + /**
  73 + * 构建 Column 对象
  74 + *
  75 + * @param tableName 表名
  76 + * @param tableAlias 别名
  77 + * @param column 字段名
  78 + * @return Column 对象
  79 + */
  80 + public static Column buildColumn(String tableName, Alias tableAlias, String column) {
  81 + return new Column(tableAlias != null ? tableAlias.getName() + "." + column : column);
  82 + }
  83 +
70 } 84 }