写点什么

基于 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")@RefreshScopepublic 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
复制代码

源码地址:https://github.com/yantaowang/kl-platform

用户头像

智慧源点

关注

终身学习、研究java架构、ai大模型 2019-12-06 加入

商业合作: wytwhdwdd

评论

发布
暂无评论
基于Sass的架构之mysql数据库_SASS_智慧源点_InfoQ写作社区