全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📝 1 篇文章 8 道配套习题

多租户与数据权限专题

专题说明

本专题系统讲解MyBatis多租户架构设计与数据权限管控的完整解决方案,涵盖三种数据库方案对比、拦截器实现、动态数据源切换、事务场景下的数据源切换陷阱以及ThreadLocal生命周期管理。

学习目标

  1. 理解多租户三种数据库方案的优缺点及适用场景
  2. 掌握基于StatementHandler拦截器的租户隔离实现
  3. 学会使用JSqlParser进行SQL AST解析与重写
  4. 掌握动态数据源切换与Spring事务的交互机制
  5. 理解ThreadLocal在多租户场景下的安全清理策略

学习内容

  • 多租户架构:独立数据库、独立Schema、共享Schema
  • 数据权限拦截器:StatementHandler拦截、JSqlParser AST重写
  • 动态数据源切换:AbstractRoutingDataSource、ThreadLocal上下文
  • 事务与数据源切换的陷阱及解决方案
  • 租户隔离策略:特权角色处理、ThreadLocal生命周期管理

学习建议

多租户是SaaS架构的核心问题,务必理解三种方案的权衡取舍。数据权限拦截器涉及JSqlParser、BoundSql等底层知识,建议结合源码调试理解。事务与数据源切换的交互是面试高频考点,也是生产环境最常见的坑。

📝 发现内容有误?点击此处直接编辑

📝 配套习题(8 题)

1
单选题

在 MyBatis 多租户架构中,采用"共享数据库、共享 Schema"方案时,实现租户数据隔离最推荐的方式是?

A

在每个 SQL 语句中手动添加 tenant_id 条件

B

通过 MyBatis 拦截器在运行时自动注入 tenant_id 过滤条件

C

为每个租户创建独立的数据库视图

D

在应用层对查询结果进行租户过滤

2
多选题

关于 MyBatis 多租户架构的三种数据库设计方案(独立数据库、独立 Schema、共享 Schema),以下说法正确的有哪些?

A

独立数据库方案的数据隔离性最强,但运维成本最高

B

独立 Schema 方案可以在同一个数据库实例中通过不同 Schema 实现租户隔离

C

共享 Schema 方案最适合租户数量庞大且单租户数据量较小的 SaaS 场景

D

独立数据库方案无法实现租户之间的数据共享需求

E

三种方案可以混合使用,例如 VIP 租户使用独立数据库,普通租户共享 Schema

3
单选题

在实现 MyBatis 数据权限拦截器时,如果要拦截并修改 SQL 语句(如添加部门数据权限过滤),应该拦截以下哪个接口?

A

Executor

B

ParameterHandler

C

StatementHandler

D

ResultSetHandler

4
多选题

在实现 MyBatis 数据权限拦截器时,以下哪些做法是正确的?

A

使用 JSqlParser 解析和重写 SQL 语句,避免字符串拼接导致的 SQL 语法错误

B

对 UPDATE 和 DELETE 语句也需要添加数据权限过滤条件

C

在拦截器中直接修改 BoundSql 的 sql 字段来实现 SQL 重写

D

通过 ThreadLocal 传递当前用户的数据权限上下文(如部门 ID 列表)

E

数据权限拦截器的 @Order 优先级应高于多租户拦截器

5
单选题

在 Spring + MyBatis 架构中实现动态数据源切换,核心组件 AbstractRoutingDataSourcedetermineCurrentLookupKey() 方法通常从哪里获取当前数据源的 key?

A

从 Spring 的 ApplicationContext 中查找

B

从数据库配置表中读取

C

从 ThreadLocal 中获取当前线程绑定的数据源标识

D

从 HTTP 请求头中解析

6
多选题

在 Spring 事务管理中结合动态数据源切换时,以下哪些说法是正确的?

A

在同一个 @Transactional 事务中可以切换到不同的数据源

B

数据源切换必须在事务开启之前完成

C

使用 @Transactional 时,Spring 会绑定事务开始时的数据源,后续切换无效

D

可以通过编程式事务(PlatformTransactionManager)在不同数据源间切换

E

分布式事务(如 Seata)可以解决跨数据源的事务一致性问题

7
单选题

在基于 ThreadLocal 实现租户隔离的系统中,以下哪个时机清理租户上下文是最安全的?

A

在每个 Controller 方法执行完毕后清理

B

在 DispatcherServlet 的 finally 块中统一清理

C

使用 Servlet Filter 或 Spring HandlerInterceptor 的 afterCompletion 方法清理

D

不需要手动清理,ThreadLocal 会在线程结束时自动清理

8
多选题

某 SaaS 平台需要实现"平台管理员可查看所有租户数据,租户管理员只能查看本租户数据"的隔离策略,以下哪些实现方案是可行的?

A

在数据权限拦截器中判断当前用户角色,平台管理员角色不注入 tenant_id 条件,其他角色注入 tenant_id 条件

B

为平台管理员和租户管理员分别创建不同的 MyBatis Mapper 接口

C

使用 MyBatis 的 @SelectProvider 动态构建 SQL,根据角色决定是否添加 tenant_id 条件

D

在数据库层面创建视图,平台管理员视图不带 tenant_id 过滤,租户管理员视图带 tenant_id 过滤

E

平台管理员查询时临时切换到一个不带租户过滤的数据源

← 上一个专题 基本 CRUD 实战专题
下一个专题 → 存储过程与高级查询专题

📝 发现内容有误?点击此处直接编辑

想查看更多习题和详细解析?
小程序提供完整的题库和详细解析

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库