适配 Oracle 数据库

1. 解决 Menu 的 permission 为空,导致缓存初始化报错
2. 多租户拦截时,过滤掉 DUAL 表,避免 TENANT_ID 字段不存在的报错
3. BaseDO 增加 creator、updator 字段的 jdbcType,避免解析 null 值报错
This commit is contained in:
YunaiV 2022-05-01 01:12:27 +08:00
parent ef9dfda300
commit 1bd86d6ffd
3 changed files with 23 additions and 9 deletions

View File

@ -4,29 +4,40 @@ import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.tenant.config.TenantProperties; import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import lombok.AllArgsConstructor;
import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue; import net.sf.jsqlparser.expression.LongValue;
import java.util.HashSet;
import java.util.Set;
/** /**
* 基于 MyBatis Plus 多租户的功能实现 DB 层面的多租户的功能 * 基于 MyBatis Plus 多租户的功能实现 DB 层面的多租户的功能
* *
* @author 芋道源码 * @author 芋道源码
*/ */
@AllArgsConstructor
public class TenantDatabaseInterceptor implements TenantLineHandler { public class TenantDatabaseInterceptor implements TenantLineHandler {
private final TenantProperties properties; private final Set<String> ignoreTables = new HashSet<>();
public TenantDatabaseInterceptor(TenantProperties properties) {
// 不同 DB 大小写的习惯不同所以需要都添加进去
properties.getIgnoreTables().forEach(table -> {
ignoreTables.add(table.toLowerCase());
ignoreTables.add(table.toUpperCase());
});
// OracleKeyGenerator 生成主键时会查询这个表查询这个表后会自动拼接 TENANT_ID 导致报错
ignoreTables.add("DUAL");
}
@Override @Override
public Expression getTenantId() { public Expression getTenantId() {
return new LongValue( TenantContextHolder.getRequiredTenantId()); return new LongValue(TenantContextHolder.getRequiredTenantId());
} }
@Override @Override
public boolean ignoreTable(String tableName) { public boolean ignoreTable(String tableName) {
return TenantContextHolder.isIgnore() // 情况一全局忽略多租户 return TenantContextHolder.isIgnore() // 情况一全局忽略多租户
|| CollUtil.contains(properties.getIgnoreTables(), tableName); // 情况二忽略多租户的表 || CollUtil.contains(ignoreTables, tableName); // 情况二忽略多租户的表
} }
} }

View File

@ -3,8 +3,8 @@ package cn.iocoder.yudao.framework.mybatis.core.dataobject;
import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import org.apache.ibatis.type.JdbcType;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
@ -32,14 +32,14 @@ public abstract class BaseDO implements Serializable {
* *
* 使用 String 类型的原因是未来可能会存在非数值的情况留好拓展性 * 使用 String 类型的原因是未来可能会存在非数值的情况留好拓展性
*/ */
@TableField(fill = FieldFill.INSERT) @TableField(fill = FieldFill.INSERT, jdbcType = JdbcType.VARCHAR)
private String creator; private String creator;
/** /**
* 更新者目前使用 SysUser id 编号 * 更新者目前使用 SysUser id 编号
* *
* 使用 String 类型的原因是未来可能会存在非数值的情况留好拓展性 * 使用 String 类型的原因是未来可能会存在非数值的情况留好拓展性
*/ */
@TableField(fill = FieldFill.INSERT_UPDATE) @TableField(fill = FieldFill.INSERT_UPDATE, jdbcType = JdbcType.VARCHAR)
private String updater; private String updater;
/** /**
* 是否删除 * 是否删除

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.service.permission; package cn.iocoder.yudao.module.system.service.permission;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO;
@ -95,7 +96,9 @@ public class MenuServiceImpl implements MenuService {
ImmutableMultimap.Builder<String, MenuDO> permMenuCacheBuilder = ImmutableMultimap.builder(); ImmutableMultimap.Builder<String, MenuDO> permMenuCacheBuilder = ImmutableMultimap.builder();
menuList.forEach(menuDO -> { menuList.forEach(menuDO -> {
menuCacheBuilder.put(menuDO.getId(), menuDO); menuCacheBuilder.put(menuDO.getId(), menuDO);
permMenuCacheBuilder.put(menuDO.getPermission(), menuDO); if (StrUtil.isNotEmpty(menuDO.getPermission())) { // 会存在 permission null 的情况导致 put NPE 异常
permMenuCacheBuilder.put(menuDO.getPermission(), menuDO);
}
}); });
menuCache = menuCacheBuilder.build(); menuCache = menuCacheBuilder.build();
permissionMenuCache = permMenuCacheBuilder.build(); permissionMenuCache = permMenuCacheBuilder.build();