You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 04:00:30