Skip to content

多数据源

Bean Searcher 支持多数据源。

静态数据源

我们可在 @SearchBean 注解中为每个实体类指定不同的数据源,例如,指定 User 实体类来自 userDs 数据源:

java
@SearchBean(dataSource="userDs")
public class User {
    // 省略其它代码
}

指定 Order 实体类来自 orderDs 数据源:

java
@SearchBean(dataSource="orderDs")
public class Order {
    // 省略其它代码
}

配置(SpringBoot 为例)

首先在配置文件 application.properties 中配置数据源信息:

properties
# 默认数据源
spring.datasource.url = jdbc:h2:~/test
spring.datasource.driverClassName = org.h2.Driver
spring.datasource.username = sa
spring.datasource.password = 123456
# user 数据源
spring.datasource.user.url = jdbc:h2:~/user
spring.datasource.user.driverClassName = org.h2.Driver
spring.datasource.user.username = sa
spring.datasource.user.password = 123456
# order 数据源
spring.datasource.order.url = jdbc:h2:~/order
spring.datasource.order.driverClassName = org.h2.Driver
spring.datasource.order.username = sa
spring.datasource.order.password = 123456

然后配置以下一些 Bean 即可:

java
// user 数据源配置信息
@Bean(name = "userDsProps")
@ConfigurationProperties(prefix = "spring.datasource.user")
public DataSourceProperties userDsProps() {
    return new DataSourceProperties();
}

// order 数据源配置信息
@Bean(name = "orderDsProps")
@ConfigurationProperties(prefix = "spring.datasource.order")
public DataSourceProperties orderDsProps() {
    return new DataSourceProperties();
}

@Bean
public NamedDataSource userNamedDataSource(@Qualifier("userDsProps") DataSourceProperties dataSourceProperties) {
    DataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().build();
    // 具名数据源:cn.zhxu.bs.boot.NamedDataSource
    return new NamedDataSource("userDs", dataSource);
}

@Bean
public NamedDataSource orderNamedDataSource(@Qualifier("orderDsProps") DataSourceProperties dataSourceProperties) {    
    DataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().build();
    // 具名数据源:cn.zhxu.bs.boot.NamedDataSource
    return new NamedDataSource("orderDs", dataSource);
}

动态数据源

上述配置的多数据源对单个 SearchBean 而言都是静态的,即某个实体类与某个数据源之间的关系是注解里指定死的。如果你开发的项目是 SAAS 模式,要求同一个实体类对不同的 Tenant(租户)使用不同数据源。则可以使用本节所讲的动态数据源。

要使用动态数据源,首先定义个 DynamicDatasource:

java
public class DynamicDatasource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        // 可以在拦截器中使用 ThreadLocal 记录当前租户信息
        // 然后在这里从 ThreadLocal 中取出
        return "当前租户编号";      // 返回当前租户编号
    }

}

然后,配置一个动态数据源(以 SpringBoot 项目为例):

java
// 把 DynamicDatasource 注册为一个 Bean
@Bean
public DataSource dynamicDatasource() {
    DynamicDatasource dynamicDatasource = new DynamicDatasource();
    dynamicDatasource.setTargetDataSources(getAllDataSources());
    return dynamicDatasource;
}

private Map<Object, Object> getAllDataSources() {
    Map<Object, Object> dataSources = new HashMap<>();
    dataSources.put("租户1编号", new DataSource1());
    dataSources.put("租户2编号", new DataSource2());
    // 把所有数据源都放进 dataSources 里
    return dataSources;
}

基于 Apache 许可发布