Solon

solon.data.dynamicds

<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon.data.dynamicds</artifactId>
</dependency>

1、描述

数据扩展插件,为 Solon Data 提供了 动态数据源 的能力扩展。(v1.11.1 之后支持)

动态数据源,常见的合适场景:

  • 主从数据架构
  • 互备数据架构
  • 读写分离数据架构

提醒:

  • 动态数据源的内部切换是借用 ThreadLocal 实现
  • 多个动态数据源时,用的是同一个 ThreadLocal(多个时,要注意这个细节)
  • 一个服务内,最好只有一个动态源
  • 有更丰富的需求时,可基于 solon.data::AbstractRoutingDataSource 自己定制

2、配置示例

# db_order 为固定数据源
test.db_order:
  schema: db_order
  jdbcUrl: jdbc:mysql://localhost:3306/db_order?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
  driverClassName: com.mysql.cj.jdbc.Driver
  username: root
  password: 123456

# db_user 为动态数据源(主菜是这里!!!)
test.db_user:
  type: "com.zaxxer.hikari.HikariDataSource"
  strict: true
  default: #default 或 master ,会做为动态源的默认源
    schema: db_user
    jdbcUrl: jdbc:mysql://localhost:3306/db_user?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
    driverClassName: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
  db_user_2:
    schema: db_user
    jdbcUrl: jdbc:mysql://localhost:3307/db_user?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
    driverClassName: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456

2、应用示例

//配置数据源 bean
@Configuration
public class Config {
    //固定数据源
    @Bean("db_order")
    public DataSource dbOrder(@Inject("${test.db_order}") HikariDataSource dataSource) {
        return dataSource;
    }
    
    //动态数据源(直接注入)
    @Bean("db_user")
    public DataSource dbUser(@Inject("${test.db_user}") DynamicDataSource dataSource) {
        return dataSource;
    }
    
    //动态数据源(手动构建)//只是示例一下
    //@Bean("db_user")
    public DataSource dsUser2(@Inject("$demo.ds.db_user}") Properties props) {
        //手动构建,可以不用配置:type, strict
        Map<String, DataSource> dsMap = DsUtils.buildDsMap(props, HikariDataSource.class);
        DataSource dsDef = dsMap.get("default");
        
        DynamicDataSource tmp = new DynamicDataSource();
        tmp.setStrict(true);
        tmp.setTargetDataSources(dsMap);
        tmp.setDefaultTargetDataSource(dsDef);
        
        return tmp;
    }
}

@Service
public class UserService{
    @Db("db_order")
    OrderMapper orderMapper;
    
    @Db("db_user")
    UserMapper userMapper;
    
    @DynamicDs //使用 db_user 动态源内的 默认源
    public void addUser(){
        userMapper.inserUser();
    }
    
    @DynamicDs("db_user_1") //使用 db_user 动态源内的 db_user_1 源
    public void getUserList(){
        userMapper.selectUserList();
    }
    
    public void getUserList2(){
        DynamicDsHolder.set("db_user_2"); //使用 db_user 动态源内的 db_user_2 源
        userMapper.selectUserList();
    }
}

具体参考

https://gitee.com/noear/solon-examples/tree/main/4.Solon-Data/demo4002-dynamicds