Java Spring Boot多数据源切换:基于配置类实现条件选择逻辑
Spring Boot 基于IF语句切换多数据源实现方案
前提确认
假设你已经完成以下配置:
application.yml中配置了两个数据源(spring.datasource.db1、spring.datasource.db2)- 两个数据源配置类(如
DataSource1Config、DataSource2Config)已定义,且分别生成了命名唯一的DataSource、SqlSessionFactory(或JdbcTemplate)等Bean
实现方案1:基于SqlSessionTemplate切换
1. 配置类补充(确保Bean命名唯一)
以DataSource1Config为例,生成对应命名的SqlSessionTemplate:
@Configuration @MapperScan(basePackages = "com.example.mapper.db1", sqlSessionTemplateRef = "sqlSessionTemplate1") public class DataSource1Config { @Bean("dataSource1") @ConfigurationProperties(prefix = "spring.datasource.db1") public DataSource dataSource1() { return DataSourceBuilder.create().build(); } @Bean("sqlSessionFactory1") public SqlSessionFactory sqlSessionFactory1(@Qualifier("dataSource1") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/db1/*.xml")); return bean.getObject(); } @Bean("sqlSessionTemplate1") public SqlSessionTemplate sqlSessionTemplate1(@Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } }
DataSource2Config做相同配置,仅需将所有db1、1替换为db2、2即可。
2. Service层IF条件切换
在业务类中注入两个SqlSessionTemplate,通过if逻辑选择使用:
@Service public class DemoService { @Autowired @Qualifier("sqlSessionTemplate1") private SqlSessionTemplate sqlSessionTemplate1; @Autowired @Qualifier("sqlSessionTemplate2") private SqlSessionTemplate sqlSessionTemplate2; public List<DemoEntity> getDemoData(boolean useDb2) { // 基于if条件切换数据源 if (useDb2) { return sqlSessionTemplate2.selectList("com.example.mapper.db2.DemoMapper.selectAll"); } else { return sqlSessionTemplate1.selectList("com.example.mapper.db1.DemoMapper.selectAll"); } } }
实现方案2:基于Mapper接口直接切换
1. 配置类说明
两个配置类的@MapperScan分别指定不同的mapper包路径,确保不同数据源的mapper接口隔离。
2. Service层IF条件切换
直接注入对应数据源的Mapper接口,通过if逻辑调用:
@Service public class DemoService { @Autowired private DemoMapper1 demoMapper1; // 属于db1的mapper接口 @Autowired private DemoMapper2 demoMapper2; // 属于db2的mapper接口 public List<DemoEntity> getDemoData(boolean useDb2) { if (useDb2) { return demoMapper2.selectAll(); } else { return demoMapper1.selectAll(); } } }
实现方案3:基于JdbcTemplate切换
如果项目使用JdbcTemplate操作数据库,同样可以用if逻辑切换:
1. 配置类补充JdbcTemplate Bean
在DataSource1Config中添加:
@Bean("jdbcTemplate1") public JdbcTemplate jdbcTemplate1(@Qualifier("dataSource1") DataSource dataSource) { return new JdbcTemplate(dataSource); }
DataSource2Config对应添加jdbcTemplate2。
2. Service层IF条件切换
@Service public class DemoService { @Autowired @Qualifier("jdbcTemplate1") private JdbcTemplate jdbcTemplate1; @Autowired @Qualifier("jdbcTemplate2") private JdbcTemplate jdbcTemplate2; public List<DemoEntity> getDemoData(boolean useDb2) { String sql = "SELECT * FROM demo"; if (useDb2) { return jdbcTemplate2.query(sql, new BeanPropertyRowMapper<>(DemoEntity.class)); } else { return jdbcTemplate1.query(sql, new BeanPropertyRowMapper<>(DemoEntity.class)); } } }
注意事项
- 所有Bean命名必须唯一,使用
@Qualifier注解明确注入目标,避免依赖注入冲突 - 若需事务支持,需为每个数据源单独配置
DataSourceTransactionManager,并在对应业务方法上指定事务管理器(如@Transactional(transactionManager = "transactionManager1")) - 该方案适合业务逻辑简单、条件明确的场景,复杂动态切换需求建议使用
AbstractRoutingDataSource实现
内容的提问来源于stack exchange,提问作者tobes
相关产品推荐
相关产品推荐

