当前位置: 首页 > news >正文

中铁建设集团好进吗优化师培训

中铁建设集团好进吗,优化师培训,汕头电商网站建设,白云做网站数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…

数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个租户标识(如 tenant_id),并在所有的数据库查询中自动加入这个租户ID作为过滤条件来实现的。

使用MyBatis-Plus实现了多租户功能

1、MybatisPlusConfig.java:配置类,通过TenantLineInnerInterceptor开启租户功能。该拦截器是关键,能自动向SQL查询添加WHERE条件。

public class MybatisPlusConfig {@Autowiredprivate TenantProperties tenantProperties;@Autowiredprivate MyTenantLineHandler myTenantLineHandler;@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();if (tenantProperties.isEnable()) { // 根据配置文件决定是否启用多租户插件TenantLineInnerInterceptor tenantLineInnerInterceptor = new TenantLineInnerInterceptor();tenantLineInnerInterceptor.setTenantLineHandler(myTenantLineHandler); // 设置我们自定义的处理器interceptor.addInnerInterceptor(tenantLineInnerInterceptor);System.out.println("INFO: TenantLineInnerInterceptor has been added to MybatisPlusInterceptor."); // 用于启动时确认}// 分页插件interceptor.addInnerInterceptor(paginationInnerInterceptor());// 乐观锁插件interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());// 阻断插件interceptor.addInnerInterceptor(blockAttackInnerInterceptor());return interceptor;}/*** 分页插件,自动识别数据库类型*/public PaginationInnerInterceptor paginationInnerInterceptor() {PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();// 设置数据库类型为mysqlpaginationInnerInterceptor.setDbType(DbType.MYSQL);// 设置最大单页限制数量,默认 500 条,-1 不受限制paginationInnerInterceptor.setMaxLimit(-1L);return paginationInnerInterceptor;}/*** 乐观锁插件*/public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() {return new OptimisticLockerInnerInterceptor();}/*** 如果是对全表的删除或更新操作,就会终止该操作*/public BlockAttackInnerInterceptor blockAttackInnerInterceptor() {return new BlockAttackInnerInterceptor();}
}

2、MyTenantLineHandler.java:自定义的TenantLineHandler实现,负责提供租户ID、列名以及指定需要过滤的表。它通过TenantUtils.getCurrentTenantId()获取租户ID,并从TenantProperties获取列名,同时判断是否需要对特定表应用过滤器。

package com.ruoyi.framework.config;import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.ruoyi.common.utils.TenantUtils;
import com.ruoyi.framework.config.properties.TenantProperties;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.Set;/*** 这个类实现了 MyBatis Plus 的 TenantLineHandler 接口,负责两件事:* 告诉拦截器当前操作的租户ID是什么。* 告诉拦截器当前操作的表是否应该被忽略。*/
@Component
public class MyTenantLineHandler implements TenantLineHandler {private static final Logger log = LoggerFactory.getLogger(MyTenantLineHandler.class);@Autowiredprivate TenantProperties tenantProperties;/*** 【核心修改】* 只有当用户选择了租户时,才返回真实的租户ID。* 否则,我们返回一个特殊的、无效的ID(如0L),并配合 shouldFilter 方法来确保拦截器不工作。*/@Overridepublic Expression getTenantId() {Long currentTenantId = TenantUtils.getCurrentTenantId();if (currentTenantId == null) {// 当没有租户ID时,返回一个不可能匹配任何记录的ID// 真实的过滤逻辑由 shouldFilter 控制return new LongValue(0L); }return new LongValue(currentTenantId);}/*** 获取租户ID的数据库字段名*/@Overridepublic String getTenantIdColumn() {return tenantProperties.getColumn(); // 从配置文件获取}/*** 这是一个总开关。只有当用户登录并明确选择了某个租户后,才允许拦截器进行SQL处理。* 否则,拦截器应忽略所有表。* @param tableName 表名* @return 是否忽略。true = 忽略,false = 不忽略(进行处理)*/@Overridepublic boolean ignoreTable(String tableName) {// 如果用户还未选择租户,则忽略所有表Long currentTenantId = TenantUtils.getCurrentTenantId();if (currentTenantId == null) {log.debug("No tenant selected, ignoring all tables.");return true;}// 如果用户已选择租户,则根据配置文件中的 ignore-tables 列表来判断Set<String> ignoreTables = tenantProperties.getIgnoreTables();boolean shouldIgnore = ignoreTables != null && ignoreTables.stream().anyMatch(item -> item.equalsIgnoreCase(tableName.trim()));if (shouldIgnore) {log.debug("Table [{}] is in ignore-tables list, skipping.", tableName);} else {log.debug("Table [{}] is not in ignore-tables list, applying tenant filter.", tableName);}return shouldIgnore;}
}

3、TenantProperties.java:从配置文件加载多租户配置,包括是否启用、租户列名(tenant_id)和忽略的表。

package com.ruoyi.framework.config.properties;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;@Component
@ConfigurationProperties(prefix = "tenant")
public class TenantProperties {/*** 是否开启多租户功能*/private boolean enable = true; // 默认开启,可以在YML中覆盖/*** 多租户 ID 的数据库字段名*/private String column = "tenant_id"; // 默认列名为 tenant_id/*** 需要忽略多租户处理的表名集合 (在配置文件中用逗号分隔)*/private Set<String> ignoreTables = new HashSet<>();// --- Getters and Setters ---public boolean isEnable() {return enable;}public void setEnable(boolean enable) {this.enable = enable;}public String getColumn() {return column;}public void setColumn(String column) {this.column = column;}public Set<String> getIgnoreTables() {return ignoreTables;}// 这个setter允许YML中用逗号分隔的字符串配置 ignoreTablespublic void setIgnoreTables(String ignoreTablesStr) {if (ignoreTablesStr != null && !ignoreTablesStr.isEmpty()) {this.ignoreTables = Set.of(ignoreTablesStr.toLowerCase().split(",")).stream().map(String::trim).collect(Collectors.toSet());} else {this.ignoreTables = new HashSet<>();}}
}

整个拦截流程 

请求进入SysProjectController后,最终调用projectMapper.selectProjectList(...)。MyBatis-Plus的TenantLineInnerInterceptor会拦截该调用,通过MyTenantLineHandler获取当前租户ID和列名,然后检查sys_project表是否需要过滤。如果需要,拦截器会自动在SQL查询的WHERE子句中添加AND tenant_id = ?,从而确保只返回当前租户的数据。 这个“拦截”行为不是在业务代码(如 Controller 或 Service)中能直接看到的,它是通过 Spring Boot 的自动配置 和 MyBatis 的插件机制 在底层实现的。具体如下:

  1.  注册拦截器 (应用启动时):在 ruoyi-framework 模块中看到的 MybatisPlusConfig.java 文件是这一切的起点。这是一个配置类。interceptor.addInnerInterceptor(tenantLineInnerInterceptor)是“连接点”!这行代码明确地将配置好的 TenantLineInnerInterceptor 注册 到了 MyBatis-Plus 的拦截器链中。

    当 Spring Boot 应用启动时,它会扫描到这个配置,执行 mybatisPlusInterceptor() 方法,创建一个包含了租户拦截器的 MybatisPlusInterceptor Bean。

  2. MyBatis 插件工作原理:

    MyBatis 自身设计了一套插件(Interceptor)机制,它允许在 SQL 执行过程的某些关键节点进行干预。这些节点包括:Executor: SQL 执行器、StatementHandler: SQL 语法构建处理器、ParameterHandler: 参数处理器、ResultSetHandler: 结果集处理器。TenantLineInnerInterceptor 正是利用了这套机制,它主要拦截的是 StatementHandler。

  3. SQL 执行时的拦截过程 (请求处理时) :前端应用发送一个请求;经过Controller -> Service -> Mapper;MyBatis 执行;进入拦截点: 在 MyBatis 将 XML 中的 SQL (select ... from sys_project ...) 转换成最终可以在数据库执行的 PreparedStatement 之前,它会触发 StatementHandler 的处理流程;TenantLineInnerInterceptor 生效: 因为我们在启动时已经注册了 TenantLineInnerInterceptor,此时它就会被激活。拦截器拿到原始的 SQL 语句。它调用我们提供的 MyTenantLineHandler,获取到当前的 tenantId (例如 123) 和租户列名 (tenant_id)。它会智能地分析原始 SQL,找到 FROM sys_project 这部分,并自动在 WHERE 条件中(或者新建一个 WHERE 条件)补充上租户过滤。

总结

拦截的动作发生在 MyBatis 执行 SQL 的生命周期内部,而不是在业务代码层面。MybatisPlusConfig.java 中的配置,就像是给 MyBatis 的执行引擎装上了一个“插件”或“mod”。一旦装上,它就会对所有经过的 SQL “自动审查和加工”,无需在每次调用 Mapper 时手动干预。

这种设计的好处是 透明和无侵入:业务开发人员只需要关注业务逻辑,而不需要关心多租户的过滤细节,框架会自动保证数据安全,大大减少了编码工作量和出错的可能性。

http://www.cadmedia.cn/news/3110.html

相关文章:

  • 网站建设营销技巧淘宝指数
  • 淘宝运营培训班学费大概多少营销推广seo
  • 彩票网站建设成本怎么制作小程序
  • 手机端h5广东百度seo关键词排名
  • ui设计看重学历吗快速优化seo软件
  • 建站免费空间网站优化搜索排名
  • 中山 环保 骏域网站建设专家北京发生大事了
  • 湖南省建设监理协会网站百度网盘网页
  • 小蝌蚪草莓站长cm统计什么是seo是什么意思
  • 该怎么给做网站的提页面需求短视频培训课程
  • 做翻译小说网站赚钱吗搜索引擎排名营销
  • 单位网站怎么制作网络口碑营销案例分析
  • 网站建设备案多长时间合肥疫情最新消息
  • 科协网站建设的建议google chrome download
  • 海口疫情最新消息今天seo网站推广目的
  • 互联网培训班可靠吗郑州seo
  • 厚街商城网站建设seo推广优化
  • 公文写作 课程中心网站建设网站申请流程
  • 济南网站建设yigeseo网站推广步骤
  • 网站建设中的html页面seo精灵
  • 杭州论坛网站制作聊城网站推广的公司
  • app商城系统开发seo型网站
  • php网站作业模版免备案域名
  • 那种导航网站江北关键词优化排名seo
  • 网站运营者网址营销推广外包
  • 萧山区seo关键词排名如何优化网络连接
  • 长沙招聘网股票发行ipo和seo是什么意思
  • 什么网站做的产品海报比较多生成关键词的软件
  • 校园网站建设与实现毕业论文淘宝店铺怎么推广
  • 咸阳网站建设xymokj常州网站推广