多数据源
多数据源
实现AbstractRoutingDataSource抽象类
新建数据源
在configuration中注入多个数据源
@Bean
public DataSource dataSource1() {
HikariDataSource hikariDataSource = new HikariDataSource();
hikariDataSource.setJdbcUrl("jdbc:mysql://192.168.18.117:3306/study");
hikariDataSource.setUsername("root");
hikariDataSource.setPassword("365373011");
hikariDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
return hikariDataSource;
}
@Bean
public DataSource dataSource2() {
HikariDataSource hikariDataSource = new HikariDataSource();
hikariDataSource.setJdbcUrl("jdbc:mysql://192.168.18.226:3306/study");
hikariDataSource.setUsername("root");
hikariDataSource.setPassword("52701314");
hikariDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
return hikariDataSource;
}
实现抽象AbstractRoutingDataSource类
配置数据源key与value之间的对应关系,根据ThreadLocal中的字符串对象来获取数据源进行切换,ThreadLocal等于w时那么就是使用DataSource1,ThreadLocal等于r时,那么就使用Data Source2.
@Configuration
public class DynamicDatasource extends AbstractRoutingDataSource {
public static ThreadLocal<String> name = new ThreadLocal<>();
@Autowired
@Qualifier("dataSource1")
private DataSource dataSource1;
@Autowired
@Qualifier("dataSource2")
private DataSource dataSource2;
@Override
protected Object determineCurrentLookupKey() {
return name.get();
}
@Override
public void afterPropertiesSet() {
Map<Object, Object> dataSourceMap = new HashMap<>();
// 设置数据源key与value之间的对应关系
dataSourceMap.put("W", dataSource1);
dataSourceMap.put("R", dataSource2);
super.setTargetDataSources(dataSourceMap);
// 设置默认数据源
super.setDefaultTargetDataSource(dataSource2);
super.afterPropertiesSet();
}
}
使用DynamicDatasource
将DynamicDatasource注入到SqlSessionFactoryBean中,依靠DynamicDatasource实现myabtis数据源的动态切换。
@Bean
public SqlSessionFactory sqlSessionFactory(@Autowired DynamicDatasource dynamicDatasource) {
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dynamicDatasource);
try {
return sqlSessionFactory.getObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
在controller中进行测试
ThreadLocal等于w时那么就是使用DataSource1,ThreadLocal等于r时,那么就使用Data Source2,这里可以采用AOP + 注解的方式进行优化,利用AOP扫描所有包,判断包下的是否有注解,如果有注解则获取注解中的value,根据value切换ThreadLocal设置ThreadLocal,以此来实现切换数据源。
@RestController
public class TestController {
@Autowired
private UserDAO userDAO;
@GetMapping("/R")
public Object test() {
DynamicDatasource.name.set("W");
return userDAO.list();
}
@GetMapping("/W")
public Object w() {
DynamicDatasource.name.set("R");
return userDAO.list();
}
}
数据库存储内容如下
数据源1:
数据源2:
执行结果如下
W接口:
R接口:
创建多个SqlSessionFactory
根据数据源的不同,创建不同的SqlSessionFactoryBean,根据不同的SqlSessionFactoryBean扫描不同的包,创建不同的mapper,根据数据源的不同导入不同数据源的mapper即可
创建多个SqlSessionFactory
mapperScan中指定了mapper路径和使用的SqlSessionFactoryBean的bean名称。
@Configuration
@MapperScan(basePackages = "com.lyra.dao.w", sqlSessionFactoryRef = "wSqlSessionFactory")
public class WDatasouce {
@Bean
public DataSource dataSource2() {
HikariDataSource hikariDataSource = new HikariDataSource();
hikariDataSource.setJdbcUrl("jdbc:mysql://192.168.18.227:3306/study");
hikariDataSource.setUsername("root");
hikariDataSource.setPassword("52701314");
hikariDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
return hikariDataSource;
}
@Bean(value = "wSqlSessionFactory")
public SqlSessionFactory wSqlSessionFactory() {
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dataSource2());
try {
return sqlSessionFactory.getObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@Configuration
@MapperScan(basePackages = "com.lyra.dao.r", sqlSessionFactoryRef = "rSqlSessionFactory")
public class DataSourceConfig {
@Bean
public DataSource dataSource1() {
HikariDataSource hikariDataSource = new HikariDataSource();
hikariDataSource.setJdbcUrl("jdbc:mysql://192.168.18.117:3306/study");
hikariDataSource.setUsername("root");
hikariDataSource.setPassword("365373011");
hikariDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
return hikariDataSource;
}
@Bean(value = "rSqlSessionFactory")
public SqlSessionFactory rSqlSessionFactory() {
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dataSource1());
try {
return sqlSessionFactory.getObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
在Mapper中根据不同的数据源创建不同的mapper
测试
执行结果和之前方法1也是一样的
W接口:
R接口:
dynamic-datasource-spring
文档: https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611
导依赖
<!-- https://mvnrepository.com/artifact/com.baomidou/dynamic-datasource-spring-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.6.1</version>
</dependency>
配置数据源
配置两个数据源分别是w和r,和一个primary数据源,如果没有使用ds注解,那么默认使用的就是primary中配置的数据源
spring:
datasource:
dynamic:
primary: w
datasource:
w:
url: jdbc:mysql://192.168.18.117:3306/study
username: root
password: 365373011
driver-class-name: com.mysql.cj.jdbc.Driver
r:
url: jdbc:mysql://192.168.18.227:3306/study
username: root
password: 52701314
driver-class-name: com.mysql.cj.jdbc.Driver
使用DS注解
利用DS注解切换不同的数据源
@RestController
public class TestController {
@Autowired
private UserDAO userDAO;
@Autowired
private WUserDAO wUserDAO;
@GetMapping("/R")
@DS("r")
public Object test() {
return wUserDAO.list();
}
@GetMapping("/W")
@DS("w")
public Object w() {
return userDAO.list();
}
}
测试
执行结果和之前方法1也是一样的
W接口:
R接口:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南