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,29 +4,40 @@ import cn.hutool.core.collection.CollUtil;
4 import cn.iocoder.yudao.framework.tenant.config.TenantProperties; 4 import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
5 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; 5 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
6 import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; 6 import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
7 -import lombok.AllArgsConstructor;  
8 import net.sf.jsqlparser.expression.Expression; 7 import net.sf.jsqlparser.expression.Expression;
9 import net.sf.jsqlparser.expression.LongValue; 8 import net.sf.jsqlparser.expression.LongValue;
10 9
  10 +import java.util.HashSet;
  11 +import java.util.Set;
  12 +
11 /** 13 /**
12 * 基于 MyBatis Plus 多租户的功能,实现 DB 层面的多租户的功能 14 * 基于 MyBatis Plus 多租户的功能,实现 DB 层面的多租户的功能
13 * 15 *
14 * @author 芋道源码 16 * @author 芋道源码
15 */ 17 */
16 -@AllArgsConstructor  
17 public class TenantDatabaseInterceptor implements TenantLineHandler { 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 @Override 32 @Override
22 public Expression getTenantId() { 33 public Expression getTenantId() {
23 - return new LongValue( TenantContextHolder.getRequiredTenantId()); 34 + return new LongValue(TenantContextHolder.getRequiredTenantId());
24 } 35 }
25 36
26 @Override 37 @Override
27 public boolean ignoreTable(String tableName) { 38 public boolean ignoreTable(String tableName) {
28 return TenantContextHolder.isIgnore() // 情况一,全局忽略多租户 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,8 +3,8 @@ package cn.iocoder.yudao.framework.mybatis.core.dataobject;
3 import com.baomidou.mybatisplus.annotation.FieldFill; 3 import com.baomidou.mybatisplus.annotation.FieldFill;
4 import com.baomidou.mybatisplus.annotation.TableField; 4 import com.baomidou.mybatisplus.annotation.TableField;
5 import com.baomidou.mybatisplus.annotation.TableLogic; 5 import com.baomidou.mybatisplus.annotation.TableLogic;
6 -import lombok.Builder;  
7 import lombok.Data; 6 import lombok.Data;
  7 +import org.apache.ibatis.type.JdbcType;
8 8
9 import java.io.Serializable; 9 import java.io.Serializable;
10 import java.util.Date; 10 import java.util.Date;
@@ -32,14 +32,14 @@ public abstract class BaseDO implements Serializable { @@ -32,14 +32,14 @@ public abstract class BaseDO implements Serializable {
32 * 32 *
33 * 使用 String 类型的原因是,未来可能会存在非数值的情况,留好拓展性。 33 * 使用 String 类型的原因是,未来可能会存在非数值的情况,留好拓展性。
34 */ 34 */
35 - @TableField(fill = FieldFill.INSERT) 35 + @TableField(fill = FieldFill.INSERT, jdbcType = JdbcType.VARCHAR)
36 private String creator; 36 private String creator;
37 /** 37 /**
38 * 更新者,目前使用 SysUser 的 id 编号 38 * 更新者,目前使用 SysUser 的 id 编号
39 * 39 *
40 * 使用 String 类型的原因是,未来可能会存在非数值的情况,留好拓展性。 40 * 使用 String 类型的原因是,未来可能会存在非数值的情况,留好拓展性。
41 */ 41 */
42 - @TableField(fill = FieldFill.INSERT_UPDATE) 42 + @TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.VARCHAR)
43 private String updater; 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 package cn.iocoder.yudao.module.system.service.permission; 1 package cn.iocoder.yudao.module.system.service.permission;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; 5 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 6 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO; 7 import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO;
@@ -95,7 +96,9 @@ public class MenuServiceImpl implements MenuService { @@ -95,7 +96,9 @@ public class MenuServiceImpl implements MenuService {
95 ImmutableMultimap.Builder<String, MenuDO> permMenuCacheBuilder = ImmutableMultimap.builder(); 96 ImmutableMultimap.Builder<String, MenuDO> permMenuCacheBuilder = ImmutableMultimap.builder();
96 menuList.forEach(menuDO -> { 97 menuList.forEach(menuDO -> {
97 menuCacheBuilder.put(menuDO.getId(), menuDO); 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 menuCache = menuCacheBuilder.build(); 103 menuCache = menuCacheBuilder.build();
101 permissionMenuCache = permMenuCacheBuilder.build(); 104 permissionMenuCache = permMenuCacheBuilder.build();