Skip to content

业务数据源配置教程

业务数据源用于让 forge-business 手写业务模块按当前租户切换到对应业务库。它和低代码运行数据源不是一回事:

类型控制范围典型使用方
平台主数据源用户、租户、菜单、权限、字典、系统配置、低代码元数据Forge 平台自身
低代码运行数据源某个低代码业务对象的动态 CRUD 读写库低代码应用中心
租户业务数据源某个租户下 forge-business 模块的 MyBatis-Plus Mapper/XML 读写库手写业务模块

租户业务数据源只影响显式声明了 @TenantBusinessDataSource 或使用 TenantBusinessDataSourceExecutor 的业务逻辑。平台表 sys_*、低代码元数据表和数据权限控制面元数据仍然走主库。

配置前提

完成页面配置之前,后端必须已经在 baomidou dynamic-datasource 中声明可用的业务库。租户表里保存的 default_business_datasource_code 必须和 dynamic-datasource 的 dsKey 完全一致。

yaml
spring:
  datasource:
    dynamic:
      primary: master
      strict: true
      datasource:
        master:
          url: jdbc:mysql://127.0.0.1:3306/forge_admin
          username: root
          password: your-password
          driver-class-name: com.mysql.cj.jdbc.Driver
        tenant_biz_demo:
          url: jdbc:mysql://127.0.0.1:3306/forge_tenant_biz_demo
          username: root
          password: your-password
          driver-class-name: com.mysql.cj.jdbc.Driver

forge:
  business:
    datasource:
      enabled: true
      tenant-routing-enabled-default: false

还需要把系统配置 business.datasource.tenant-routing-enabled 调整为 true。Flyway 会初始化该配置,默认值是 false,目的是避免未准备业务库时误切库。

操作流程

1. 新增租户业务数据源

进入“开发者工具 / 数据源管理”,点击“新增数据源”。

重点字段:

字段填写说明
数据源名称给运维和业务人员看的名称,例如“租户 A 业务库”
数据源编码必须等于 spring.datasource.dynamic.datasource 下的 dsKey,例如 tenant_biz_demo
用途范围选择“租户业务”
风险等级旧系统生产库建议选“高”
只读模式只读库开启后会禁止运行写入和 DDL
允许运行写入业务调试和正式写入需要设置为“允许”
允许运行 DDL租户业务库一般保持“禁止”,除非明确允许平台创建演示表或业务表
启用状态必须为“启用”才会出现在租户配置下拉框

数据源管理配置租户业务用途

注意:这里的数据源记录用于后台页面选择、权限提示和连接测试。真正的 ORM 切库仍由 dynamic-datasource 控制,所以只在页面新增数据源、不在 application.yml 配置同名 dsKey,会在运行时提示“租户业务数据源未在 dynamic-datasource 中配置”。

2. 绑定租户默认业务库

进入“系统管理 / 租户管理”,编辑目标租户,在“业务数据源”分组中选择“默认业务库”。

保存后,租户表会记录:

  • default_business_datasource_id:页面选择的数据源 ID。
  • default_business_datasource_code:实际用于 dynamic-datasource 切换的 dsKey。

如果不选择默认业务库,forge-business 会回退到 master

租户管理绑定默认业务库

3. 打开业务数据源调试台验证

进入“应用中心 / 业务数据源调试”。

推荐验证顺序:

  1. 选择租户。
  2. 点击“检测路由”,确认“租户配置”和“线程 dsKey”是否为目标 dsKey。
  3. 点击“写入测试记录”,调试接口会在当前路由的数据源中自动创建 business_datasource_demo 表并写入一条记录。
  4. 点击“读取记录”,确认记录只出现在当前租户对应业务库。

业务数据源调试台验证路由

调试台返回的关键字段:

字段判断方式
当前数据库应显示为目标业务库名称
线程 dsKey应等于租户绑定的 default_business_datasource_code
路由状态业务库表示已切换;主库表示配置关闭或租户未绑定
routeKey写入演示记录时记录当前 dynamic-datasource key

业务代码如何接入

普通 Web 请求中,业务 Service 标注 @TenantBusinessDataSource 即可。Mapper 仍然按 MyBatis-Plus 和 XML 正常写,不需要手动拿 JdbcTemplate

java
@Service
@RequiredArgsConstructor
public class ContractService {

    private final ContractMapper contractMapper;

    @TenantBusinessDataSource
    @Transactional(rollbackFor = Exception.class)
    public Long createContract(Contract contract) {
        contractMapper.insert(contract);
        return contract.getId();
    }
}

定时任务、消息消费、补偿任务这类没有登录态的场景,应显式传入租户 ID:

java
@Component
@RequiredArgsConstructor
public class ContractJob {

    private final TenantBusinessDataSourceExecutor dataSourceExecutor;
    private final ContractMapper contractMapper;

    public void refreshTenantContracts(Long tenantId) {
        dataSourceExecutor.execute(tenantId, () -> {
            contractMapper.refreshStatistics();
            return null;
        });
    }
}

@Async 和项目线程池会通过 TenantBusinessDataSourceTaskDecorator 传播租户和 dynamic-datasource 上下文;任务结束后会恢复线程原上下文,避免串库。

数据权限和平台表

切到业务库以后,业务 SQL 不能再依赖业务库里存在平台表。当前实现已经做了控制面隔离:

  • sys_data_scope_config
  • sys_role
  • sys_role_data_scope
  • sys_org
  • sys_region_code

这些表会从 forge.datascope.metadata-datasource 加载,默认是 master。数据权限拦截器运行时只读取内存快照,并把行政区划权限解析成业务库可执行的字面量条件,不会在业务库里查询 sys_region_code

如果你的业务 Mapper 需要数据权限,请确保业务主表自身存在配置中引用的业务字段,例如 tenant_idcreate_bycreate_deptregion_code。自定义数据权限 SQL 不要写跨平台表子查询。

常见问题

选择了租户业务库,但调试台仍显示 master

按顺序检查:

  1. forge.business.datasource.enabled 是否为 true
  2. 系统配置 business.datasource.tenant-routing-enabled 是否为 true
  3. 租户是否保存了“默认业务库”。
  4. 数据源编码是否和 dynamic-datasource dsKey 完全一致。
  5. 业务方法是否标注 @TenantBusinessDataSource,或是否通过 TenantBusinessDataSourceExecutor 执行。

报“租户业务数据源未在 dynamic-datasource 中配置”

说明租户表保存了某个 default_business_datasource_code,但 spring.datasource.dynamic.datasource 中没有同名 dsKey。把两边编码改一致后重启后端。

Table '<业务库>.sys_data_scope_config' doesn't exist

说明还有旧代码或自定义 SQL 在业务库查询平台控制面表。新实现下数据权限控制面元数据应从 master 快照读取;业务库只保存业务表。检查自定义数据权限 SQL,避免引用 sys_* 平台表。

写入测试记录失败

调试接口会自动创建 business_datasource_demo 表。若失败,通常是业务库账号没有建表权限,或数据源被配置为只读、禁止写入。生产库不建议用调试写入,先在测试业务库验证路由。

推荐验收清单

  • 数据源管理中存在用途为“租户业务”的数据源,且编码等于 dynamic-datasource dsKey。
  • 租户管理中目标租户已绑定默认业务库。
  • 全局开关和系统配置开关都已启用。
  • 调试台“检测路由”显示目标 dsKey。
  • 调试台写入记录后,目标业务库出现 business_datasource_demo 表和对应租户数据。
  • 实际业务 Service 使用 @TenantBusinessDataSource,Mapper/XML 查询不引用平台表。