基于 Sass 的架构之 mysql 数据库
作者:智慧源点
- 2024-02-25 北京
本文字数:2274 字
阅读完需:约 7 分钟
本系列主要解决多租户的产品,想在表内级别上,实现租户数据隔离(分表、分库方案不在本文讨论范围内)
TenantLineInnerInterceptor 是 MybatisPlus 中提供的多租户插件
基于 MybatisPlus 的多租户插件实现步骤如下:
1、引入 maven 依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<!-- 截止本文编写时,最新的MP版本 -->
<version>3.5.3.1</version>
</dependency>
复制代码
2、实现代码如下:
/**
* 多租户配置
*/
@Setter
@Getter
@ConfigurationProperties(prefix = "kl.tenant")
@RefreshScope
public class TenantProperties {
/**
* 是否开启多租户
*/
private Boolean enable = false;
/**
* 配置不进行多租户隔离的表名
*/
private List<String> ignoreTables = new ArrayList<>();
/**
* 配置不进行多租户隔离的sql
* 需要配置mapper的全路径如:com.central.user.mapper.SysUserMapper.findList
*/
private List<String> ignoreSqls = new ArrayList<>();
}
复制代码
/**
* 多租户自动配置
*
* @author zlt
* @date 2019/8/5
*/
@EnableConfigurationProperties(TenantProperties.class)
public class TenantAutoConfigure {
@Autowired
private TenantProperties tenantProperties;
@Bean
public TenantLineHandler tenantLineHandler() {
return new TenantLineHandler() {
/**
* 获取租户id
*/
@Override
public Expression getTenantId() {
Integer tenantId = KlThreadLocal.getPartnerCode();
if (tenantId != null) {
return new StringValue(tenantId.toString());
}
return new NullValue();
}
/**
* 过滤不需要根据租户隔离的表
* @param tableName 表名
*/
@Override
public boolean ignoreTable(String tableName) {
return tenantProperties.getIgnoreTables().stream().anyMatch(
(e) -> e.equalsIgnoreCase(tableName)
);
}
};
}
}
复制代码
public class CustomTenantInterceptor extends TenantLineInnerInterceptor {
private List<String> ignoreSqls;
public CustomTenantInterceptor(TenantLineHandler tenantLineHandler, List<String> ignoreSqls) {
super(tenantLineHandler);
this.ignoreSqls = ignoreSqls;
}
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds
, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
if (isIgnoreMappedStatement(ms.getId())) {
return;
}
super.beforeQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql);
}
private boolean isIgnoreMappedStatement(String msId) {
return ignoreSqls.stream().anyMatch((e) -> e.equalsIgnoreCase(msId));
}
}
复制代码
/**
* mybatis-plus自动配置
*
*/
@EnableConfigurationProperties({MybatisPlusAutoFillProperties.class})
public class MybatisPlusAutoConfigure {
@Autowired
private TenantLineHandler tenantLineHandler;
@Autowired
private TenantProperties tenantProperties;
@Autowired
private MybatisPlusAutoFillProperties autoFillProperties;
/**
* 分页插件,自动识别数据库类型
*/
@Bean
public MybatisPlusInterceptor paginationInterceptor() {
MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
boolean enableTenant = tenantProperties.getEnable();
//是否开启多租户隔离
if (enableTenant) {
CustomTenantInterceptor tenantInterceptor = new CustomTenantInterceptor(
tenantLineHandler, tenantProperties.getIgnoreSqls());
mpInterceptor.addInnerInterceptor(tenantInterceptor);
}
mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return mpInterceptor;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "kl.mybatis-plus.auto-fill", name = "enabled", havingValue = "true", matchIfMissing = true)
public MetaObjectHandler metaObjectHandler() {
return new DateMetaObjectHandler(autoFillProperties);
}
}
复制代码
3、应用配置
#
kl:
#多租户配置
tenant:
enable: true
ignoreTables:
- sys_user
- sys_role_user
- sys_role_menu
ignoreSqls:
# 用户关联角色时,显示所有角色
- com.central.user.mapper.SysRoleMapper.findAll
# 用户列表显示用户所关联的所有角色
- com.central.user.mapper.SysUserRoleMapper.findRolesByUserIds
复制代码
划线
评论
复制
发布于: 刚刚阅读数: 3
智慧源点
关注
终身学习、研究java架构、ai大模型 2019-12-06 加入
商业合作: wytwhdwdd
评论