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 自己定制
与事务注解一起使用时,会失效!!!(v2.8.0 后,支持事务注解管理)
2、数据源构建
- 使用配置构建数据源(具体参考:《数据源的配置与构建》)
# db_order 为固定数据源
solon.dataSources.db_order:
class: "com.zaxxer.hikari.HikariDataSource"
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 为动态数据源(主菜是这里!!!)
solon.dataSources.db_user:
class: "org.noear.solon.data.dynamicds.DynamicDataSource"
strict: true #严格模式(指定的源不存时:严格模式会抛异常;非严格模式用默认源)
default: "db_user_1" #指定默认数据源
db_user_1:
dataSourceClassName: "com.zaxxer.hikari.HikariDataSource"
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:
dataSourceClassName: "com.zaxxer.hikari.HikariDataSource"
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
- 使用代码构建数据源
//配置数据源 bean
@Configuration
public class Config {
//动态数据源(手动构建)//只是示例一下
//@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;
}
}
3、“注解” 或 “手动” 切换动态数据源
@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();
}
}
4、通过纯代码创建和网络管理(示例)
@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