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: "db_user_1" #指定默认数据源
db_user_1:
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;
}
}
@Component
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(){
//手动设置二级源
DynamicDsKey.setCurrent("db_user_2"); //使用 db_user 动态源内的 db_user_2 源
userMapper.selectUserList();
}
}
3、通过纯代码创建和网络管理
@Configuration
public class DemoConfig {
@Bean
public DynamicDataSource dsInit(){
DynamicDataSource ds = new DynamicDataSource();
ds.setDefaultTargetDataSource(...); //设置默认的源 //也可能没有默认
return ds;
}
}
@Controller
public class DemoController{
@Inject
DynamicDataSource ds;
//添加
@Mapping("ds/add")
public void dsAdd(String dsName, String dsProps){
Props props = new Props();
props.loadAdd(Utils.buildProperties(dsProps));
DataSource ds = props.getBean(HikariDataSource.class);
ds.addTargetDataSource(dsName, ds);
}
//注解设置二级源
@DynamicDs("${dsName}") //注解设置当前取用哪源
@Mapping("ds/use")
public void dsUse(String dsName){
...
//如果想直接拿到数据源对象:ds.getTargetDataSource(dsName);
//除了注解设置二级源,还可以手动设置:DynamicDsKey.setCurrent(dsName);
}
}
具体参考
https://gitee.com/noear/solon-examples/tree/main/4.Solon-Data/demo4002-dynamicds