Commit 2b39b434fac1fa7d4a0e382e8ab9fe5552499eef

Authored by YunaiV
1 parent 40deb00a

【依赖】mybatis-plus from 3.5.5 to 3.5.7

Showing 21 changed files with 90 additions and 519 deletions
yudao-dependencies/pom.xml
... ... @@ -23,10 +23,11 @@
23 23 <knife4j.version>4.3.0</knife4j.version>
24 24 <!-- DB 相关 -->
25 25 <druid.version>1.2.23</druid.version>
26   - <mybatis-plus.version>3.5.5</mybatis-plus.version>
27   - <mybatis-plus-generator.version>3.5.5</mybatis-plus-generator.version>
  26 + <mybatis.version>3.5.16</mybatis.version>
  27 + <mybatis-plus.version>3.5.7</mybatis-plus.version>
  28 + <mybatis-plus-generator.version>3.5.7</mybatis-plus-generator.version>
28 29 <dynamic-datasource.version>4.3.1</dynamic-datasource.version>
29   - <mybatis-plus-join.version>1.4.10</mybatis-plus-join.version>
  30 + <mybatis-plus-join.version>1.4.13</mybatis-plus-join.version>
30 31 <easy-trans.version>2.2.11</easy-trans.version>
31 32 <redisson.version>3.26.0</redisson.version>
32 33 <dm8.jdbc.version>8.1.3.62</dm8.jdbc.version>
... ... @@ -172,6 +173,11 @@
172 173 <version>${druid.version}</version>
173 174 </dependency>
174 175 <dependency>
  176 + <groupId>org.mybatis</groupId>
  177 + <artifactId>mybatis</artifactId>
  178 + <version>${mybatis.version}</version>
  179 + </dependency>
  180 + <dependency>
175 181 <groupId>com.baomidou</groupId>
176 182 <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
177 183 <version>${mybatis-plus.version}</version>
... ...
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java
... ... @@ -7,19 +7,17 @@ import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRuleFac
7 7 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
8 8 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
9 9 import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
10   -import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport;
  10 +import com.baomidou.mybatisplus.extension.plugins.inner.BaseMultiTableInnerInterceptor;
  11 +import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor;
11 12 import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
12 13 import lombok.Getter;
13 14 import lombok.RequiredArgsConstructor;
14   -import net.sf.jsqlparser.expression.*;
  15 +import net.sf.jsqlparser.expression.Expression;
15 16 import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
16   -import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
17   -import net.sf.jsqlparser.expression.operators.relational.ExistsExpression;
18   -import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
19   -import net.sf.jsqlparser.expression.operators.relational.InExpression;
20 17 import net.sf.jsqlparser.schema.Table;
21 18 import net.sf.jsqlparser.statement.delete.Delete;
22   -import net.sf.jsqlparser.statement.select.*;
  19 +import net.sf.jsqlparser.statement.select.Select;
  20 +import net.sf.jsqlparser.statement.select.WithItem;
23 21 import net.sf.jsqlparser.statement.update.Update;
24 22 import org.apache.ibatis.executor.Executor;
25 23 import org.apache.ibatis.executor.statement.StatementHandler;
... ... @@ -30,20 +28,25 @@ import org.apache.ibatis.session.ResultHandler;
30 28 import org.apache.ibatis.session.RowBounds;
31 29  
32 30 import java.sql.Connection;
33   -import java.util.*;
  31 +import java.util.Collections;
  32 +import java.util.List;
  33 +import java.util.Map;
  34 +import java.util.Set;
34 35 import java.util.concurrent.ConcurrentHashMap;
35 36  
36 37 /**
37 38 * 数据权限拦截器,通过 {@link DataPermissionRule} 数据权限规则,重写 SQL 的方式来实现
38   - * 主要的 SQL 重写方法,可见 {@link #builderExpression(Expression, List)} 方法
  39 + * 主要的 SQL 重写方法,可见 {@link #buildTableExpression(Table, Expression, String)} 方法
39 40 *
40 41 * 整体的代码实现上,参考 {@link com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor} 实现。
41 42 * 所以每次 MyBatis Plus 升级时,需要 Review 下其具体的实现是否有变更!
42 43 *
  44 + * 为什么不直接基于 {@link DataPermissionInterceptor} 实现?因为它是 MyBatis Plus 3.5.2 版本才出来,当时 yudao 已经实现数据权限了!
  45 + *
43 46 * @author 芋道源码
44 47 */
45 48 @RequiredArgsConstructor
46   -public class DataPermissionDatabaseInterceptor extends JsqlParserSupport implements InnerInterceptor {
  49 +public class DataPermissionDatabaseInterceptor extends BaseMultiTableInnerInterceptor implements InnerInterceptor {
47 50  
48 51 private final DataPermissionRuleFactory ruleFactory;
49 52  
... ... @@ -101,10 +104,11 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
101 104  
102 105 @Override
103 106 protected void processSelect(Select select, int index, String sql, Object obj) {
104   - processSelectBody(select.getSelectBody());
  107 + final String whereSegment = (String) obj;
  108 + processSelectBody(select, whereSegment);
105 109 List<WithItem> withItemsList = select.getWithItemsList();
106 110 if (!CollectionUtils.isEmpty(withItemsList)) {
107   - withItemsList.forEach(this::processSelectBody);
  111 + withItemsList.forEach(withItem -> processSelectBody(withItem, whereSegment));
108 112 }
109 113 }
110 114  
... ... @@ -113,8 +117,10 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
113 117 */
114 118 @Override
115 119 protected void processUpdate(Update update, int index, String sql, Object obj) {
116   - final Table table = update.getTable();
117   - update.setWhere(this.builderExpression(update.getWhere(), table));
  120 + final Expression sqlSegment = getUpdateOrDeleteExpression(update.getTable(), update.getWhere(), (String) obj);
  121 + if (null != sqlSegment) {
  122 + update.setWhere(sqlSegment);
  123 + }
118 124 }
119 125  
120 126 /**
... ... @@ -122,367 +128,16 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
122 128 */
123 129 @Override
124 130 protected void processDelete(Delete delete, int index, String sql, Object obj) {
125   - delete.setWhere(this.builderExpression(delete.getWhere(), delete.getTable()));
126   - }
127   -
128   - // ========== 和 TenantLineInnerInterceptor 一致的逻辑 ==========
129   -
130   - protected void processSelectBody(SelectBody selectBody) {
131   - if (selectBody == null) {
132   - return;
133   - }
134   - if (selectBody instanceof PlainSelect) {
135   - processPlainSelect((PlainSelect) selectBody);
136   - } else if (selectBody instanceof WithItem) {
137   - WithItem withItem = (WithItem) selectBody;
138   - processSelectBody(withItem.getSubSelect().getSelectBody());
139   - } else {
140   - SetOperationList operationList = (SetOperationList) selectBody;
141   - List<SelectBody> selectBodyList = operationList.getSelects();
142   - if (CollectionUtils.isNotEmpty(selectBodyList)) {
143   - selectBodyList.forEach(this::processSelectBody);
144   - }
145   - }
146   - }
147   -
148   - /**
149   - * 处理 PlainSelect
150   - */
151   - protected void processPlainSelect(PlainSelect plainSelect) {
152   - //#3087 github
153   - List<SelectItem> selectItems = plainSelect.getSelectItems();
154   - if (CollectionUtils.isNotEmpty(selectItems)) {
155   - selectItems.forEach(this::processSelectItem);
156   - }
157   -
158   - // 处理 where 中的子查询
159   - Expression where = plainSelect.getWhere();
160   - processWhereSubSelect(where);
161   -
162   - // 处理 fromItem
163   - FromItem fromItem = plainSelect.getFromItem();
164   - List<Table> list = processFromItem(fromItem);
165   - List<Table> mainTables = new ArrayList<>(list);
166   -
167   - // 处理 join
168   - List<Join> joins = plainSelect.getJoins();
169   - if (CollectionUtils.isNotEmpty(joins)) {
170   - mainTables = processJoins(mainTables, joins);
171   - }
172   -
173   - // 当有 mainTable 时,进行 where 条件追加
174   - if (CollectionUtils.isNotEmpty(mainTables)) {
175   - plainSelect.setWhere(builderExpression(where, mainTables));
176   - }
177   - }
178   -
179   - private List<Table> processFromItem(FromItem fromItem) {
180   - // 处理括号括起来的表达式
181   - while (fromItem instanceof ParenthesisFromItem) {
182   - fromItem = ((ParenthesisFromItem) fromItem).getFromItem();
183   - }
184   -
185   - List<Table> mainTables = new ArrayList<>();
186   - // 无 join 时的处理逻辑
187   - if (fromItem instanceof Table) {
188   - Table fromTable = (Table) fromItem;
189   - mainTables.add(fromTable);
190   - } else if (fromItem instanceof SubJoin) {
191   - // SubJoin 类型则还需要添加上 where 条件
192   - List<Table> tables = processSubJoin((SubJoin) fromItem);
193   - mainTables.addAll(tables);
194   - } else {
195   - // 处理下 fromItem
196   - processOtherFromItem(fromItem);
197   - }
198   - return mainTables;
199   - }
200   -
201   - /**
202   - * 处理where条件内的子查询
203   - * <p>
204   - * 支持如下:
205   - * 1. in
206   - * 2. =
207   - * 3. >
208   - * 4. <
209   - * 5. >=
210   - * 6. <=
211   - * 7. <>
212   - * 8. EXISTS
213   - * 9. NOT EXISTS
214   - * <p>
215   - * 前提条件:
216   - * 1. 子查询必须放在小括号中
217   - * 2. 子查询一般放在比较操作符的右边
218   - *
219   - * @param where where 条件
220   - */
221   - protected void processWhereSubSelect(Expression where) {
222   - if (where == null) {
223   - return;
224   - }
225   - if (where instanceof FromItem) {
226   - processOtherFromItem((FromItem) where);
227   - return;
228   - }
229   - if (where.toString().indexOf("SELECT") > 0) {
230   - // 有子查询
231   - if (where instanceof BinaryExpression) {
232   - // 比较符号 , and , or , 等等
233   - BinaryExpression expression = (BinaryExpression) where;
234   - processWhereSubSelect(expression.getLeftExpression());
235   - processWhereSubSelect(expression.getRightExpression());
236   - } else if (where instanceof InExpression) {
237   - // in
238   - InExpression expression = (InExpression) where;
239   - Expression inExpression = expression.getRightExpression();
240   - if (inExpression instanceof SubSelect) {
241   - processSelectBody(((SubSelect) inExpression).getSelectBody());
242   - }
243   - } else if (where instanceof ExistsExpression) {
244   - // exists
245   - ExistsExpression expression = (ExistsExpression) where;
246   - processWhereSubSelect(expression.getRightExpression());
247   - } else if (where instanceof NotExpression) {
248   - // not exists
249   - NotExpression expression = (NotExpression) where;
250   - processWhereSubSelect(expression.getExpression());
251   - } else if (where instanceof Parenthesis) {
252   - Parenthesis expression = (Parenthesis) where;
253   - processWhereSubSelect(expression.getExpression());
254   - }
255   - }
256   - }
257   -
258   - protected void processSelectItem(SelectItem selectItem) {
259   - if (selectItem instanceof SelectExpressionItem) {
260   - SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem;
261   - if (selectExpressionItem.getExpression() instanceof SubSelect) {
262   - processSelectBody(((SubSelect) selectExpressionItem.getExpression()).getSelectBody());
263   - } else if (selectExpressionItem.getExpression() instanceof Function) {
264   - processFunction((Function) selectExpressionItem.getExpression());
265   - }
266   - }
267   - }
268   -
269   - /**
270   - * 处理函数
271   - * <p>支持: 1. select fun(args..) 2. select fun1(fun2(args..),args..)<p>
272   - * <p> fixed gitee pulls/141</p>
273   - *
274   - * @param function
275   - */
276   - protected void processFunction(Function function) {
277   - ExpressionList parameters = function.getParameters();
278   - if (parameters != null) {
279   - parameters.getExpressions().forEach(expression -> {
280   - if (expression instanceof SubSelect) {
281   - processSelectBody(((SubSelect) expression).getSelectBody());
282   - } else if (expression instanceof Function) {
283   - processFunction((Function) expression);
284   - }
285   - });
286   - }
287   - }
288   -
289   - /**
290   - * 处理子查询等
291   - */
292   - protected void processOtherFromItem(FromItem fromItem) {
293   - // 去除括号
294   - while (fromItem instanceof ParenthesisFromItem) {
295   - fromItem = ((ParenthesisFromItem) fromItem).getFromItem();
296   - }
297   -
298   - if (fromItem instanceof SubSelect) {
299   - SubSelect subSelect = (SubSelect) fromItem;
300   - if (subSelect.getSelectBody() != null) {
301   - processSelectBody(subSelect.getSelectBody());
302   - }
303   - } else if (fromItem instanceof ValuesList) {
304   - logger.debug("Perform a subQuery, if you do not give us feedback");
305   - } else if (fromItem instanceof LateralSubSelect) {
306   - LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem;
307   - if (lateralSubSelect.getSubSelect() != null) {
308   - SubSelect subSelect = lateralSubSelect.getSubSelect();
309   - if (subSelect.getSelectBody() != null) {
310   - processSelectBody(subSelect.getSelectBody());
311   - }
312   - }
  131 + final Expression sqlSegment = getUpdateOrDeleteExpression(delete.getTable(), delete.getWhere(), (String) obj);
  132 + if (null != sqlSegment) {
  133 + delete.setWhere(sqlSegment);
313 134 }
314 135 }
315 136  
316   - /**
317   - * 处理 sub join
318   - *
319   - * @param subJoin subJoin
320   - * @return Table subJoin 中的主表
321   - */
322   - private List<Table> processSubJoin(SubJoin subJoin) {
323   - List<Table> mainTables = new ArrayList<>();
324   - if (subJoin.getJoinList() != null) {
325   - List<Table> list = processFromItem(subJoin.getLeft());
326   - mainTables.addAll(list);
327   - mainTables = processJoins(mainTables, subJoin.getJoinList());
328   - }
329   - return mainTables;
330   - }
331   -
332   - /**
333   - * 处理 joins
334   - *
335   - * @param mainTables 可以为 null
336   - * @param joins join 集合
337   - * @return List<Table> 右连接查询的 Table 列表
338   - */
339   - private List<Table> processJoins(List<Table> mainTables, List<Join> joins) {
340   - // join 表达式中最终的主表
341   - Table mainTable = null;
342   - // 当前 join 的左表
343   - Table leftTable = null;
344   -
345   - if (mainTables == null) {
346   - mainTables = new ArrayList<>();
347   - } else if (mainTables.size() == 1) {
348   - mainTable = mainTables.get(0);
349   - leftTable = mainTable;
350   - }
351   -
352   - //对于 on 表达式写在最后的 join,需要记录下前面多个 on 的表名
353   - Deque<List<Table>> onTableDeque = new LinkedList<>();
354   - for (Join join : joins) {
355   - // 处理 on 表达式
356   - FromItem joinItem = join.getRightItem();
357   -
358   - // 获取当前 join 的表,subJoint 可以看作是一张表
359   - List<Table> joinTables = null;
360   - if (joinItem instanceof Table) {
361   - joinTables = new ArrayList<>();
362   - joinTables.add((Table) joinItem);
363   - } else if (joinItem instanceof SubJoin) {
364   - joinTables = processSubJoin((SubJoin) joinItem);
365   - }
366   -
367   - if (joinTables != null) {
368   -
369   - // 如果是隐式内连接
370   - if (join.isSimple()) {
371   - mainTables.addAll(joinTables);
372   - continue;
373   - }
374   -
375   - // 当前表是否忽略
376   - Table joinTable = joinTables.get(0);
377   -
378   - List<Table> onTables = null;
379   - // 如果不要忽略,且是右连接,则记录下当前表
380   - if (join.isRight()) {
381   - mainTable = joinTable;
382   - if (leftTable != null) {
383   - onTables = Collections.singletonList(leftTable);
384   - }
385   - } else if (join.isLeft()) {
386   - onTables = Collections.singletonList(joinTable);
387   - } else if (join.isInner()) {
388   - if (mainTable == null) {
389   - onTables = Collections.singletonList(joinTable);
390   - } else {
391   - onTables = Arrays.asList(mainTable, joinTable);
392   - }
393   - mainTable = null;
394   - }
395   -
396   - mainTables = new ArrayList<>();
397   - if (mainTable != null) {
398   - mainTables.add(mainTable);
399   - }
400   -
401   - // 获取 join 尾缀的 on 表达式列表
402   - Collection<Expression> originOnExpressions = join.getOnExpressions();
403   - // 正常 join on 表达式只有一个,立刻处理
404   - if (originOnExpressions.size() == 1 && onTables != null) {
405   - List<Expression> onExpressions = new LinkedList<>();
406   - onExpressions.add(builderExpression(originOnExpressions.iterator().next(), onTables));
407   - join.setOnExpressions(onExpressions);
408   - leftTable = joinTable;
409   - continue;
410   - }
411   - // 表名压栈,忽略的表压入 null,以便后续不处理
412   - onTableDeque.push(onTables);
413   - // 尾缀多个 on 表达式的时候统一处理
414   - if (originOnExpressions.size() > 1) {
415   - Collection<Expression> onExpressions = new LinkedList<>();
416   - for (Expression originOnExpression : originOnExpressions) {
417   - List<Table> currentTableList = onTableDeque.poll();
418   - if (CollectionUtils.isEmpty(currentTableList)) {
419   - onExpressions.add(originOnExpression);
420   - } else {
421   - onExpressions.add(builderExpression(originOnExpression, currentTableList));
422   - }
423   - }
424   - join.setOnExpressions(onExpressions);
425   - }
426   - leftTable = joinTable;
427   - } else {
428   - processOtherFromItem(joinItem);
429   - leftTable = null;
430   - }
431   - }
432   -
433   - return mainTables;
434   - }
435   -
436 137 // ========== 和 TenantLineInnerInterceptor 存在差异的逻辑:关键,实现权限条件的拼接 ==========
437 138  
438   - /**
439   - * 处理条件
440   - *
441   - * @param currentExpression 当前 where 条件
442   - * @param table 单个表
443   - */
444   - protected Expression builderExpression(Expression currentExpression, Table table) {
445   - return this.builderExpression(currentExpression, Collections.singletonList(table));
446   - }
447   -
448   - /**
449   - * 处理条件
450   - *
451   - * @param currentExpression 当前 where 条件
452   - * @param tables 多个表
453   - */
454   - protected Expression builderExpression(Expression currentExpression, List<Table> tables) {
455   - // 没有表需要处理直接返回
456   - if (CollectionUtils.isEmpty(tables)) {
457   - return currentExpression;
458   - }
459   -
460   - // 第一步,获得 Table 对应的数据权限条件
461   - Expression dataPermissionExpression = null;
462   - for (Table table : tables) {
463   - // 构建每个表的权限 Expression 条件
464   - Expression expression = buildDataPermissionExpression(table);
465   - if (expression == null) {
466   - continue;
467   - }
468   - // 合并到 dataPermissionExpression 中
469   - dataPermissionExpression = dataPermissionExpression == null ? expression
470   - : new AndExpression(dataPermissionExpression, expression);
471   - }
472   -
473   - // 第二步,合并多个 Expression 条件
474   - if (dataPermissionExpression == null) {
475   - return currentExpression;
476   - }
477   - if (currentExpression == null) {
478   - return dataPermissionExpression;
479   - }
480   - // ① 如果表达式为 Or,则需要 (currentExpression) AND dataPermissionExpression
481   - if (currentExpression instanceof OrExpression) {
482   - return new AndExpression(new Parenthesis(currentExpression), dataPermissionExpression);
483   - }
484   - // ② 如果表达式为 And,则直接返回 where AND dataPermissionExpression
485   - return new AndExpression(currentExpression, dataPermissionExpression);
  139 + protected Expression getUpdateOrDeleteExpression(final Table table, final Expression where, final String whereSegment) {
  140 + return andExpression(table, where, whereSegment);
486 141 }
487 142  
488 143 /**
... ... @@ -491,7 +146,8 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
491 146 * @param table 表
492 147 * @return Expression 过滤条件
493 148 */
494   - private Expression buildDataPermissionExpression(Table table) {
  149 + @Override
  150 + public Expression buildTableExpression(Table table, Expression where, String whereSegment) {
495 151 // 生成条件
496 152 Expression allExpression = null;
497 153 for (DataPermissionRule rule : ContextHolder.getRules()) {
... ...
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java
... ... @@ -156,7 +156,8 @@ public class DeptDataPermissionRule implements DataPermissionRule {
156 156 }
157 157 // 拼接条件
158 158 return new InExpression(MyBatisUtils.buildColumn(tableName, tableAlias, columnName),
159   - new ExpressionList(CollectionUtils.convertList(deptIds, LongValue::new)));
  159 + // Parenthesis 的目的,是提供 (1,2,3) 的 () 左右括号
  160 + new Parenthesis(new ExpressionList<>(CollectionUtils.convertList(deptIds, LongValue::new))));
160 161 }
161 162  
162 163 private Expression buildUserExpression(String tableName, Alias tableAlias, Boolean self, Long userId) {
... ...
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest2.java
... ... @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
7 7 import net.sf.jsqlparser.expression.Alias;
8 8 import net.sf.jsqlparser.expression.Expression;
9 9 import net.sf.jsqlparser.expression.LongValue;
  10 +import net.sf.jsqlparser.expression.Parenthesis;
10 11 import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
11 12 import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
12 13 import net.sf.jsqlparser.expression.operators.relational.InExpression;
... ... @@ -71,9 +72,9 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
71 72 @Override
72 73 public Expression getExpression(String tableName, Alias tableAlias) {
73 74 Column column = MyBatisUtils.buildColumn(tableName, tableAlias, COLUMN);
74   - ExpressionList values = new ExpressionList(new LongValue(10L),
  75 + ExpressionList<LongValue> values = new ExpressionList<>(new LongValue(10L),
75 76 new LongValue(20L));
76   - return new InExpression(column, values);
  77 + return new InExpression(column, new Parenthesis((values)));
77 78 }
78 79  
79 80 };
... ... @@ -262,7 +263,7 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
262 263 "right join entity2 e2 on e1.id = e2.id",
263 264 "SELECT * FROM entity e " +
264 265 "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
265   - "RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1 " +
  266 + "RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e.tenant_id = 1 " +
266 267 "WHERE e2.tenant_id = 1");
267 268  
268 269 assertSql("SELECT * FROM entity e " +
... ...
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
... ... @@ -185,8 +185,8 @@ public interface BaseMapperX&lt;T&gt; extends MPJBaseMapper&lt;T&gt; {
185 185 return Db.updateBatchById(entities, size);
186 186 }
187 187  
188   - default Boolean insertOrUpdate(T entity) {
189   - return Db.saveOrUpdate(entity);
  188 + default boolean insertOrUpdate(T entity) {
  189 + return Db.saveOrUpdate(entity);
190 190 }
191 191  
192 192 default Boolean insertOrUpdateBatch(Collection<T> collection) {
... ...
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/type/JsonLongSetTypeHandler.java deleted
1   -package cn.iocoder.yudao.framework.mybatis.core.type;
2   -
3   -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
4   -import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
5   -import com.fasterxml.jackson.core.type.TypeReference;
6   -
7   -import java.util.Set;
8   -
9   -/**
10   - * 参考 {@link com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler} 实现
11   - * 在我们将字符串反序列化为 Set 并且泛型为 Long 时,如果每个元素的数值太小,会被处理成 Integer 类型,导致可能存在隐性的 BUG。
12   - *
13   - * 例如说哦,SysUserDO 的 postIds 属性
14   - *
15   - * @author 芋道源码
16   - */
17   -public class JsonLongSetTypeHandler extends AbstractJsonTypeHandler<Object> {
18   -
19   - private static final TypeReference<Set<Long>> TYPE_REFERENCE = new TypeReference<Set<Long>>(){};
20   -
21   - @Override
22   - protected Object parse(String json) {
23   - return JsonUtils.parseObject(json, TYPE_REFERENCE);
24   - }
25   -
26   - @Override
27   - protected String toJson(Object obj) {
28   - return JsonUtils.toJsonString(obj);
29   - }
30   -
31   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/image/AiImageDO.java
1 1 package cn.iocoder.yudao.module.ai.dal.dataobject.image;
2 2  
3 3 import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
4   -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
5 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
6 5 import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
7 6 import cn.iocoder.yudao.module.ai.enums.image.AiImageStatusEnum;
... ... @@ -10,7 +9,6 @@ import com.baomidou.mybatisplus.annotation.IdType;
10 9 import com.baomidou.mybatisplus.annotation.TableField;
11 10 import com.baomidou.mybatisplus.annotation.TableId;
12 11 import com.baomidou.mybatisplus.annotation.TableName;
13   -import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
14 12 import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
15 13 import lombok.Data;
16 14 import org.springframework.ai.openai.OpenAiImageOptions;
... ... @@ -107,7 +105,7 @@ public class AiImageDO extends BaseDO {
107 105 /**
108 106 * mj buttons 按钮
109 107 */
110   - @TableField(typeHandler = ButtonTypeHandler.class)
  108 + @TableField(typeHandler = JacksonTypeHandler.class)
111 109 private List<MidjourneyApi.Button> buttons;
112 110  
113 111 /**
... ... @@ -117,19 +115,5 @@ public class AiImageDO extends BaseDO {
117 115 */
118 116 private String taskId;
119 117  
120   - public static class ButtonTypeHandler extends AbstractJsonTypeHandler<Object> {
121   -
122   - @Override
123   - protected Object parse(String json) {
124   - return JsonUtils.parseArray(json, MidjourneyApi.Button.class);
125   - }
126   -
127   - @Override
128   - protected String toJson(Object obj) {
129   - return JsonUtils.toJsonString(obj);
130   - }
131   -
132   - }
133   -
134 118 }
135 119  
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/definition/BpmUserGroupDO.java
... ... @@ -2,11 +2,14 @@ package cn.iocoder.yudao.module.bpm.dal.dataobject.definition;
2 2  
3 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
5   -import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
6 5 import com.baomidou.mybatisplus.annotation.TableField;
7 6 import com.baomidou.mybatisplus.annotation.TableId;
8 7 import com.baomidou.mybatisplus.annotation.TableName;
9   -import lombok.*;
  8 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
  9 +import lombok.AllArgsConstructor;
  10 +import lombok.Builder;
  11 +import lombok.Data;
  12 +import lombok.NoArgsConstructor;
10 13  
11 14 import java.util.Set;
12 15  
... ... @@ -44,7 +47,7 @@ public class BpmUserGroupDO extends BaseDO {
44 47 /**
45 48 * 成员用户编号数组
46 49 */
47   - @TableField(typeHandler = JsonLongSetTypeHandler.class)
  50 + @TableField(typeHandler = JacksonTypeHandler.class)
48 51 private Set<Long> userIds;
49 52  
50 53 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/dataobject/file/FileConfigDO.java
... ... @@ -17,6 +17,8 @@ import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
17 17 import com.fasterxml.jackson.core.type.TypeReference;
18 18 import lombok.*;
19 19  
  20 +import java.lang.reflect.Field;
  21 +
20 22 /**
21 23 * 文件配置表
22 24 *
... ... @@ -65,8 +67,16 @@ public class FileConfigDO extends BaseDO {
65 67  
66 68 public static class FileClientConfigTypeHandler extends AbstractJsonTypeHandler<Object> {
67 69  
  70 + public FileClientConfigTypeHandler(Class<?> type) {
  71 + super(type);
  72 + }
  73 +
  74 + public FileClientConfigTypeHandler(Class<?> type, Field field) {
  75 + super(type, field);
  76 + }
  77 +
68 78 @Override
69   - protected Object parse(String json) {
  79 + public Object parse(String json) {
70 80 FileClientConfig config = JsonUtils.parseObjectQuietly(json, new TypeReference<>() {});
71 81 if (config != null) {
72 82 return config;
... ... @@ -92,7 +102,7 @@ public class FileConfigDO extends BaseDO {
92 102 }
93 103  
94 104 @Override
95   - protected String toJson(Object obj) {
  105 + public String toJson(Object obj) {
96 106 return JsonUtils.toJsonString(obj);
97 107 }
98 108  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java
... ... @@ -100,7 +100,7 @@ public class ProductCommentDO extends BaseDO {
100 100 *
101 101 * 关联 {@link ProductSkuDO#getProperties()}
102 102 */
103   - @TableField(typeHandler = ProductSkuDO.PropertyTypeHandler.class)
  103 + @TableField(typeHandler = JacksonTypeHandler.class)
104 104 private List<ProductSkuDO.Property> skuProperties;
105 105  
106 106 /**
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java
1 1 package cn.iocoder.yudao.module.product.dal.dataobject.sku;
2 2  
3   -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
4 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
5 4 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
6 5 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
... ... @@ -9,7 +8,7 @@ import com.baomidou.mybatisplus.annotation.KeySequence;
9 8 import com.baomidou.mybatisplus.annotation.TableField;
10 9 import com.baomidou.mybatisplus.annotation.TableId;
11 10 import com.baomidou.mybatisplus.annotation.TableName;
12   -import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
  11 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
13 12 import lombok.*;
14 13  
15 14 import java.util.List;
... ... @@ -43,7 +42,7 @@ public class ProductSkuDO extends BaseDO {
43 42 /**
44 43 * 属性数组,JSON 格式
45 44 */
46   - @TableField(typeHandler = PropertyTypeHandler.class)
  45 + @TableField(typeHandler = JacksonTypeHandler.class)
47 46 private List<Property> properties;
48 47 /**
49 48 * 商品价格,单位:分
... ... @@ -131,21 +130,6 @@ public class ProductSkuDO extends BaseDO {
131 130  
132 131 }
133 132  
134   - // TODO @芋艿:可以找一些新的思路
135   - public static class PropertyTypeHandler extends AbstractJsonTypeHandler<Object> {
136   -
137   - @Override
138   - protected Object parse(String json) {
139   - return JsonUtils.parseArray(json, Property.class);
140   - }
141   -
142   - @Override
143   - protected String toJson(Object obj) {
144   - return JsonUtils.toJsonString(obj);
145   - }
146   -
147   - }
148   -
149 133 // TODO 芋艿:integral from y
150 134 // TODO 芋艿:pinkPrice from y
151 135 // TODO 芋艿:seckillPrice from y
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java
1 1 package cn.iocoder.yudao.module.promotion.dal.dataobject.reward;
2 2  
3   -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
4 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
5 4 import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
6 5 import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum;
... ... @@ -10,7 +9,7 @@ import com.baomidou.mybatisplus.annotation.KeySequence;
10 9 import com.baomidou.mybatisplus.annotation.TableField;
11 10 import com.baomidou.mybatisplus.annotation.TableId;
12 11 import com.baomidou.mybatisplus.annotation.TableName;
13   -import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
  12 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
14 13 import lombok.Data;
15 14 import lombok.EqualsAndHashCode;
16 15  
... ... @@ -76,7 +75,7 @@ public class RewardActivityDO extends BaseDO {
76 75 /**
77 76 * 优惠规则的数组
78 77 */
79   - @TableField(typeHandler = RuleTypeHandler.class)
  78 + @TableField(typeHandler = JacksonTypeHandler.class)
80 79 private List<Rule> rules;
81 80  
82 81 /**
... ... @@ -115,19 +114,4 @@ public class RewardActivityDO extends BaseDO {
115 114  
116 115 }
117 116  
118   - // TODO @芋艿:可以找一些新的思路
119   - public static class RuleTypeHandler extends AbstractJsonTypeHandler<List<Rule>> {
120   -
121   - @Override
122   - protected List<Rule> parse(String json) {
123   - return JsonUtils.parseArray(json, Rule.class);
124   - }
125   -
126   - @Override
127   - protected String toJson(List<Rule> obj) {
128   - return JsonUtils.toJsonString(obj);
129   - }
130   -
131   - }
132   -
133 117 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/aftersale/AfterSaleDO.java
... ... @@ -124,7 +124,7 @@ public class AfterSaleDO extends BaseDO {
124 124 *
125 125 * 冗余 {@link TradeOrderItemDO#getProperties()}
126 126 */
127   - @TableField(typeHandler = TradeOrderItemDO.PropertyTypeHandler.class)
  127 + @TableField(typeHandler = JacksonTypeHandler.class)
128 128 private List<TradeOrderItemDO.Property> properties;
129 129 /**
130 130 * 商品图片
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderItemDO.java
1 1 package cn.iocoder.yudao.module.trade.dal.dataobject.order;
2 2  
3   -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
4 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
5 4 import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO;
6 5 import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO;
7 6 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
8 7 import com.baomidou.mybatisplus.annotation.TableField;
9 8 import com.baomidou.mybatisplus.annotation.TableName;
10   -import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
  9 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
11 10 import lombok.Data;
12 11 import lombok.EqualsAndHashCode;
13 12 import lombok.experimental.Accessors;
... ... @@ -74,7 +73,7 @@ public class TradeOrderItemDO extends BaseDO {
74 73 *
75 74 * 冗余 ProductSkuDO 的 properties 字段
76 75 */
77   - @TableField(typeHandler = PropertyTypeHandler.class)
  76 + @TableField(typeHandler = JacksonTypeHandler.class)
78 77 private List<Property> properties;
79 78 /**
80 79 * 商品图片
... ... @@ -210,20 +209,5 @@ public class TradeOrderItemDO extends BaseDO {
210 209  
211 210 }
212 211  
213   - // TODO @芋艿:可以找一些新的思路
214   - public static class PropertyTypeHandler extends AbstractJsonTypeHandler<List<Property>> {
215   -
216   - @Override
217   - protected List<Property> parse(String json) {
218   - return JsonUtils.parseArray(json, Property.class);
219   - }
220   -
221   - @Override
222   - protected String toJson(List<Property> obj) {
223   - return JsonUtils.toJsonString(obj);
224   - }
225   -
226   - }
227   -
228 212 }
229 213  
... ...
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessageRespVO.java
... ... @@ -2,12 +2,12 @@ package cn.iocoder.yudao.module.mp.controller.admin.message.vo.message;
2 2  
3 3 import cn.iocoder.yudao.module.mp.dal.dataobject.message.MpMessageDO;
4 4 import com.baomidou.mybatisplus.annotation.TableField;
  5 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
5 6 import io.swagger.v3.oas.annotations.media.Schema;
6 7 import lombok.Data;
7 8 import me.chanjar.weixin.common.api.WxConsts;
8 9  
9 10 import java.time.LocalDateTime;
10   -import java.util.Date;
11 11 import java.util.List;
12 12  
13 13 @Schema(description = "管理后台 - 公众号消息 Response VO")
... ... @@ -81,7 +81,7 @@ public class MpMessageRespVO {
81 81 *
82 82 * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS
83 83 */
84   - @TableField(typeHandler = MpMessageDO.ArticleTypeHandler.class)
  84 + @TableField(typeHandler = JacksonTypeHandler.class)
85 85 private List<MpMessageDO.Article> articles;
86 86  
87 87 @Schema(description = "音乐链接 消息类型为 music 时,才有值", example = "https://www.iocoder.cn/xxx.mp3")
... ...
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/menu/MpMenuDO.java
... ... @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.annotation.KeySequence;
7 7 import com.baomidou.mybatisplus.annotation.TableField;
8 8 import com.baomidou.mybatisplus.annotation.TableId;
9 9 import com.baomidou.mybatisplus.annotation.TableName;
  10 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
10 11 import lombok.Data;
11 12 import lombok.EqualsAndHashCode;
12 13 import lombok.ToString;
... ... @@ -163,7 +164,7 @@ public class MpMenuDO extends BaseDO {
163 164 *
164 165 * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS
165 166 */
166   - @TableField(typeHandler = MpMessageDO.ArticleTypeHandler.class)
  167 + @TableField(typeHandler = JacksonTypeHandler.class)
167 168 private List<MpMessageDO.Article> replyArticles;
168 169  
169 170 /**
... ...
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/message/MpAutoReplyDO.java
... ... @@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.annotation.KeySequence;
9 9 import com.baomidou.mybatisplus.annotation.TableField;
10 10 import com.baomidou.mybatisplus.annotation.TableId;
11 11 import com.baomidou.mybatisplus.annotation.TableName;
  12 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
12 13 import lombok.Data;
13 14 import lombok.EqualsAndHashCode;
14 15 import lombok.ToString;
... ... @@ -143,7 +144,7 @@ public class MpAutoReplyDO extends BaseDO {
143 144 *
144 145 * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS
145 146 */
146   - @TableField(typeHandler = MpMessageDO.ArticleTypeHandler.class)
  147 + @TableField(typeHandler = JacksonTypeHandler.class)
147 148 private List<MpMessageDO.Article> responseArticles;
148 149  
149 150 /**
... ...
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/message/MpMessageDO.java
1 1 package cn.iocoder.yudao.module.mp.dal.dataobject.message;
2 2  
3   -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
4 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
5 4 import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
6 5 import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO;
... ... @@ -9,12 +8,14 @@ import com.baomidou.mybatisplus.annotation.KeySequence;
9 8 import com.baomidou.mybatisplus.annotation.TableField;
10 9 import com.baomidou.mybatisplus.annotation.TableId;
11 10 import com.baomidou.mybatisplus.annotation.TableName;
12   -import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
13   -import lombok.*;
  11 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
  12 +import jakarta.validation.constraints.NotEmpty;
  13 +import lombok.Data;
  14 +import lombok.EqualsAndHashCode;
  15 +import lombok.ToString;
14 16 import me.chanjar.weixin.common.api.WxConsts;
15 17 import me.chanjar.weixin.mp.builder.kefu.NewsBuilder;
16 18  
17   -import jakarta.validation.constraints.NotEmpty;
18 19 import java.io.Serializable;
19 20 import java.util.List;
20 21  
... ... @@ -173,7 +174,7 @@ public class MpMessageDO extends BaseDO {
173 174 *
174 175 * 消息类型为 {@link WxConsts.XmlMsgType} 的 NEWS
175 176 */
176   - @TableField(typeHandler = ArticleTypeHandler.class)
  177 + @TableField(typeHandler = JacksonTypeHandler.class)
177 178 private List<Article> articles;
178 179  
179 180 /**
... ... @@ -238,18 +239,4 @@ public class MpMessageDO extends BaseDO {
238 239  
239 240 }
240 241  
241   - // TODO @芋艿:可以找一些新的思路
242   - public static class ArticleTypeHandler extends AbstractJsonTypeHandler<List<Article>> {
243   -
244   - @Override
245   - protected List<Article> parse(String json) {
246   - return JsonUtils.parseArray(json, Article.class);
247   - }
248   -
249   - @Override
250   - protected String toJson(List<Article> obj) {
251   - return JsonUtils.toJsonString(obj);
252   - }
253   -
254   - }
255 242 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/RoleDO.java
1 1 package cn.iocoder.yudao.module.system.dal.dataobject.permission;
2 2  
3 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4   -import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
5   -import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
6 4 import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
  5 +import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
7 6 import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
8 7 import com.baomidou.mybatisplus.annotation.KeySequence;
9 8 import com.baomidou.mybatisplus.annotation.TableField;
10 9 import com.baomidou.mybatisplus.annotation.TableId;
11 10 import com.baomidou.mybatisplus.annotation.TableName;
  11 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
12 12 import lombok.Data;
13 13 import lombok.EqualsAndHashCode;
14 14  
... ... @@ -72,7 +72,7 @@ public class RoleDO extends TenantBaseDO {
72 72 *
73 73 * 适用于 {@link #dataScope} 的值为 {@link DataScopeEnum#DEPT_CUSTOM} 时
74 74 */
75   - @TableField(typeHandler = JsonLongSetTypeHandler.class)
  75 + @TableField(typeHandler = JacksonTypeHandler.class)
76 76 private Set<Long> dataScopeDeptIds;
77 77  
78 78 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/tenant/TenantPackageDO.java
... ... @@ -2,10 +2,10 @@ package cn.iocoder.yudao.module.system.dal.dataobject.tenant;
2 2  
3 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
5   -import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
6 5 import com.baomidou.mybatisplus.annotation.KeySequence;
7 6 import com.baomidou.mybatisplus.annotation.TableField;
8 7 import com.baomidou.mybatisplus.annotation.TableName;
  8 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
9 9 import lombok.*;
10 10  
11 11 import java.util.Set;
... ... @@ -46,7 +46,7 @@ public class TenantPackageDO extends BaseDO {
46 46 /**
47 47 * 关联的菜单编号
48 48 */
49   - @TableField(typeHandler = JsonLongSetTypeHandler.class)
  49 + @TableField(typeHandler = JacksonTypeHandler.class)
50 50 private Set<Long> menuIds;
51 51  
52 52 }
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/user/AdminUserDO.java
1 1 package cn.iocoder.yudao.module.system.dal.dataobject.user;
2 2  
3 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4   -import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
5 4 import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
6 5 import cn.iocoder.yudao.module.system.enums.common.SexEnum;
7 6 import com.baomidou.mybatisplus.annotation.KeySequence;
8 7 import com.baomidou.mybatisplus.annotation.TableField;
9 8 import com.baomidou.mybatisplus.annotation.TableId;
10 9 import com.baomidou.mybatisplus.annotation.TableName;
  10 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
11 11 import lombok.*;
12 12 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
13 13  
... ... @@ -58,7 +58,7 @@ public class AdminUserDO extends TenantBaseDO {
58 58 /**
59 59 * 岗位编号数组
60 60 */
61   - @TableField(typeHandler = JsonLongSetTypeHandler.class)
  61 + @TableField(typeHandler = JacksonTypeHandler.class)
62 62 private Set<Long> postIds;
63 63 /**
64 64 * 用户邮箱
... ...