Commit 1bd86d6ffd8d53bce07e594bcb2b3243fe177983
1 parent
ef9dfda3
适配 Oracle 数据库
1. 解决 Menu 的 permission 为空,导致缓存初始化报错 2. 多租户拦截时,过滤掉 DUAL 表,避免 TENANT_ID 字段不存在的报错 3. BaseDO 增加 creator、updator 字段的 jdbcType,避免解析 null 值报错
Showing
3 changed files
with
23 additions
and
9 deletions
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(); |