前几天有个需求, 需要使用不同的数据源, 例如某业务要用 A 数据源, 另一个业务要用 B 数据源. 我上网收集了一些资料整合了一下, 虽然最后这个需求不了了之了, 但是多数据源动态切换还是蛮好用的, 所以记录一下, 或许以后有用呢? 或者自己感兴趣又想玩呢!
1. 加个依赖
- <dependency>
- <groupId>org.mybatis.spring.boot</groupId>
- <artifactId>mybatis-spring-boot-starter</artifactId>
- <version>1.3.1</version>
- </dependency>
2.application.properties 配置文件
- # 主从数据库
- master.db.driverClassName=com.MySQL.jdbc.Driver
- master.db.url=jdbc:MySQL://localhost:3306/cbd?characterEncoding=UTF-8&useUnicode=true&useSSL=false
- master.db.username=root
- master.db.password=admin
- slave.db.driverClassName=com.MySQL.jdbc.Driver
- slave.db.url=jdbc:MySQL://localhost:3306/cbd_test?characterEncoding=UTF-8&useUnicode=true&useSSL=false
- slave.db.username=root
- slave.db.password=admin
- mybatis.config-location= classpath:config/mybatis-config.xml
- mybatis.mapper-locations=classpath:mapper/**/*.xml
- 3. 禁用 springboot 默认加载数据源配置
- @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
- public class Application {
- public static void main(String[] args) throws Exception {
- SpringApplication.run(Application.class, args);
- }
- }
- 4. 数据源配置类
- /**
- * 主数据源
- */
- @Configuration
- @ConfigurationProperties(prefix = "master.db")
- public class MasterDataSourceConfig {
- private String url;
- private String username;
- private String password;
- private String driverClassName;
- }
- /**
- * 从数据源配置
- */
- @Configuration
- @ConfigurationProperties(prefix = "slave.db")
- public class SlaveDataSourceConfig {
- private String url;
- private String username;
- private String password;
- private String driverClassName;
- }
- /**
- * 数据源配置类
- */
- @Configuration
- public class DataSourceComponent {
- @Resource
- private MasterDataSourceConfig masterDataSourceConfig;
- @Resource
- private SlaveDataSourceConfig slaveDataSourceConfig;
- @Bean(name = "master")
- public DataSource masterDataSource() {
- DataSource dataSource = new DataSource();
- dataSource.setUrl(masterDataSourceConfig.getUrl());
- dataSource.setUsername(masterDataSourceConfig.getUsername());
- dataSource.setPassword(masterDataSourceConfig.getPassword());
- dataSource.setDriverClassName(masterDataSourceConfig.getDriverClassName());
- return dataSource;
- }
- @Bean(name = "slave")
- public DataSource slaveDataSource() {
- DataSource dataSource = new DataSource();
- dataSource.setUrl(slaveDataSourceConfig.getUrl());
- dataSource.setUsername(slaveDataSourceConfig.getUsername());
- dataSource.setPassword(slaveDataSourceConfig.getPassword());
- dataSource.setDriverClassName(slaveDataSourceConfig.getDriverClassName());
- return dataSource;
- }
- @Primary// 不加这个会报错.
- @Bean(name = "multiDataSource")
- public MultiRouteDataSource exampleRouteDataSource() {
- MultiRouteDataSource multiDataSource = new MultiRouteDataSource();
- Map<Object, Object> targetDataSources = new HashMap<>();
- targetDataSources.put("master", masterDataSource());
- targetDataSources.put("slave", slaveDataSource());
- multiDataSource.setTargetDataSources(targetDataSources);
- multiDataSource.setDefaultTargetDataSource(masterDataSource());
- return multiDataSource;
- }
- }
5. 数据源上下文
- /**
- * 数据源上下文
- */
- public class DataSourceContext {
- private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
- public static void setDataSource(String value) {
- contextHolder.set(value);
- }
- public static String getDataSource() {
- return contextHolder.get();
- }
- public static void clearDataSource() {
- contextHolder.remove();
- }
- }
6.DataSource 路由类
- /*
- * 重写的函数决定了最后选择的 DataSource
- */
- public class MultiRouteDataSource extends AbstractRoutingDataSource {
- @Override
- protected Object determineCurrentLookupKey() {
- // 通过绑定线程的数据源上下文实现多数据源的动态切换, 有兴趣的可以去查阅资料或源码
- return DataSourceContext.getDataSource();
- }
- }
7. 使用, 修改上下文中的数据源就可以切换自己想要使用的数据源了.
- public UserVO findUser(String username) {
- DataSourceContext.setDataSource("slave");
- UserVO userVO = userMapper.findByVO(username);
- System.out.println(userVO.getName()+"=====================");
- return null;
- }
这种是在业务中使用代码设置数据源的方式, 也可以使用 AOP + 注解的方式实现控制, 方法多多!
来源: https://www.cnblogs.com/tinyj/p/9864128.html