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 | 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(); | ... | ... |