Commit 1bd86d6ffd8d53bce07e594bcb2b3243fe177983

Authored by YunaiV
1 parent ef9dfda3

适配 Oracle 数据库

1. 解决 Menu 的 permission 为空,导致缓存初始化报错
2. 多租户拦截时,过滤掉 DUAL 表,避免 TENANT_ID 字段不存在的报错
3. BaseDO 增加 creator、updator 字段的 jdbcType,避免解析 null 值报错
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java
... ... @@ -4,29 +4,40 @@ import cn.hutool.core.collection.CollUtil;
4 4 import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
5 5 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
6 6 import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
7   -import lombok.AllArgsConstructor;
8 7 import net.sf.jsqlparser.expression.Expression;
9 8 import net.sf.jsqlparser.expression.LongValue;
10 9  
  10 +import java.util.HashSet;
  11 +import java.util.Set;
  12 +
11 13 /**
12 14 * 基于 MyBatis Plus 多租户的功能,实现 DB 层面的多租户的功能
13 15 *
14 16 * @author 芋道源码
15 17 */
16   -@AllArgsConstructor
17 18 public class TenantDatabaseInterceptor implements TenantLineHandler {
18 19  
19   - private final TenantProperties properties;
  20 + private final Set<String> ignoreTables = new HashSet<>();
  21 +
  22 + public TenantDatabaseInterceptor(TenantProperties properties) {
  23 + // 不同 DB 下,大小写的习惯不同,所以需要都添加进去
  24 + properties.getIgnoreTables().forEach(table -> {
  25 + ignoreTables.add(table.toLowerCase());
  26 + ignoreTables.add(table.toUpperCase());
  27 + });
  28 + // 在 OracleKeyGenerator 中,生成主键时,会查询这个表,查询这个表后,会自动拼接 TENANT_ID 导致报错
  29 + ignoreTables.add("DUAL");
  30 + }
20 31  
21 32 @Override
22 33 public Expression getTenantId() {
23   - return new LongValue( TenantContextHolder.getRequiredTenantId());
  34 + return new LongValue(TenantContextHolder.getRequiredTenantId());
24 35 }
25 36  
26 37 @Override
27 38 public boolean ignoreTable(String tableName) {
28 39 return TenantContextHolder.isIgnore() // 情况一,全局忽略多租户
29   - || CollUtil.contains(properties.getIgnoreTables(), tableName); // 情况二,忽略多租户的表
  40 + || CollUtil.contains(ignoreTables, tableName); // 情况二,忽略多租户的表
30 41 }
31 42  
32 43 }
... ...
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/dataobject/BaseDO.java
... ... @@ -3,8 +3,8 @@ package cn.iocoder.yudao.framework.mybatis.core.dataobject;
3 3 import com.baomidou.mybatisplus.annotation.FieldFill;
4 4 import com.baomidou.mybatisplus.annotation.TableField;
5 5 import com.baomidou.mybatisplus.annotation.TableLogic;
6   -import lombok.Builder;
7 6 import lombok.Data;
  7 +import org.apache.ibatis.type.JdbcType;
8 8  
9 9 import java.io.Serializable;
10 10 import java.util.Date;
... ... @@ -32,14 +32,14 @@ public abstract class BaseDO implements Serializable {
32 32 *
33 33 * 使用 String 类型的原因是,未来可能会存在非数值的情况,留好拓展性。
34 34 */
35   - @TableField(fill = FieldFill.INSERT)
  35 + @TableField(fill = FieldFill.INSERT, jdbcType = JdbcType.VARCHAR)
36 36 private String creator;
37 37 /**
38 38 * 更新者,目前使用 SysUser 的 id 编号
39 39 *
40 40 * 使用 String 类型的原因是,未来可能会存在非数值的情况,留好拓展性。
41 41 */
42   - @TableField(fill = FieldFill.INSERT_UPDATE)
  42 + @TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.VARCHAR)
43 43 private String updater;
44 44 /**
45 45 * 是否删除
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
1 1 package cn.iocoder.yudao.module.system.service.permission;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.StrUtil;
4 5 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
5 6 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 7 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO;
... ... @@ -95,7 +96,9 @@ public class MenuServiceImpl implements MenuService {
95 96 ImmutableMultimap.Builder<String, MenuDO> permMenuCacheBuilder = ImmutableMultimap.builder();
96 97 menuList.forEach(menuDO -> {
97 98 menuCacheBuilder.put(menuDO.getId(), menuDO);
98   - permMenuCacheBuilder.put(menuDO.getPermission(), menuDO);
  99 + if (StrUtil.isNotEmpty(menuDO.getPermission())) { // 会存在 permission 为 null 的情况,导致 put 报 NPE 异常
  100 + permMenuCacheBuilder.put(menuDO.getPermission(), menuDO);
  101 + }
99 102 });
100 103 menuCache = menuCacheBuilder.build();
101 104 permissionMenuCache = permMenuCacheBuilder.build();
... ...