SpringBoot整合多数据源配置实战

近期在处理项目整合的task,涉及到多数据源配置,现将具体实践分享给大家。

配置多数据源

1.application.yml配置

first:
  datasource:
    password: *****
    url: *****
    username: *****
second:
  datasource:
    password: *****
    url: *****
    username: *****

2.数据源配置类

项目结构如下:
SpringBoot整合多数据源配置实战)

@Configuration
@MapperScan(basePackages = FirstDataSourceConfig.MAPPER_PACKAGE, sqlSessionFactoryRef = "firstSqlSessionFactory")
public class FirstDataSourceConfig {

    static final String MAPPER_PACKAGE = "***.mapper.first";
    private static final String MAPPER_LOCATION = "classpath:mapper/first/*.xml";

    @Bean(value = "firstDataSource")
    @ConfigurationProperties(prefix = "first.datasource")
    public DataSource dataSourceManager() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "firstTransactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("firstDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "firstSqlSessionFactory")
    public SqlSessionFactory firstSqlSessionFactory1(@Qualifier("firstDataSource") DataSource dataSource)
            throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setConfigLocation(resolver.getResource(Constants.MYBATIS_CONFIG_PATH));
        sessionFactory.setMapperLocations(resolver.getResources(MAPPER_LOCATION));
        return sessionFactory.getObject();
    }
}
@Configuration
@MapperScan(basePackages = SecondDataSourceConfig.MAPPER_PACKAGE, sqlSessionFactoryRef = "secondSqlSessionFactory")
public class SecondDataSourceConfig {

    static final String MAPPER_PACKAGE = "***.mapper.second";
    private static final String MAPPER_LOCATION = "classpath:mapper/second/*.xml";

    @Bean(value = "secondDataSource")
    @ConfigurationProperties(prefix = "second.datasource")
    public DataSource dataSourceManager() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "secondTransactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("secondDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "secondSqlSessionFactory")
    public SqlSessionFactory secondSqlSessionFactory2(@Qualifier("secondDataSource") DataSource dataSource)
            throws Exception {
        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setConfigLocation(resolver.getResource(Constants.MYBATIS_CONFIG_PATH));
        sessionFactory.setMapperLocations(resolver.getResources(MAPPER_LOCATION));
        return sessionFactory.getObject();
    }
}
MapperScan注解定义了持久层的扫包范围,并且指定这个包配置的是哪个数据源。
@ConfigurationProperties(prefix = "xxx.xxx")可以依靠指定的前缀,使用application.yml中指定数据源的配置。
sessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver().getResource(Constants.MYBATIS_CONFIG_PATH)): 自定义数据源不会自动加载MybatisAutoConfiguration.java这个配置类里面的sqlSessionFactory,也就不会自动加载mybatis-config.xml配置文件,需手动加载。
事务处理:@Transactional(rollbackFor = Exception.class, transactionManager = "firstTransactionManager")

3.demo测试

@RunWith(SpringRunner.class)
@Slf4j
@SpringBootTest
public class DataSourceTest {

    @Resource
    private KnowledgeRecordMapper knowledgeRecordMapper;
    @Resource
    private CourseUnitMapper courseUnitMapper;

    @Test
    public void dataSourceTest() throws Exception {
    	//数据来自于first数据源
        DocumentRecordItem item = knowledgeRecordMapper.getDocumentRecordById(13439l);
        if (Objects.isNull(item)) {
            return;
        }
        log.info("documentRecord: {}", item.toString());

		//数据来自于second数据源
        List<Long> unitIds = Arrays.asList(552l, 1268l);
        List<UnitKnowledgeExaminedStatusPO> list = courseUnitMapper.getUnitKnowledgeExaminedStatusFromResult(unitIds);
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        log.info("list: {}", list);
    }
}

结果如下:

2020-11-03 14:26:00,246000 [INFO] [] [] main DruidDataSource.java:init:1003 - {dataSource-1} inited
2020-11-03 14:26:00,852000 [INFO] [] [] main DataSourceTest.java:dataSourceTest:39 - documentRecord: {"ctime":1575023698000,"documentName":"1575023700097.xlsx","id":13439,"operationDetail":"-","operationType":21,"operatorId":30000302,"operatorName":"***","utime":1575023698000}
2020-11-03 14:26:00,883000 [INFO] [] [] main DruidDataSource.java:init:1003 - {dataSource-2} inited
2020-11-03 14:26:00,964000 [INFO] [] [] main DataSourceTest.java:dataSourceTest:46 - list:[{"answerQuestionUserCount":6,"unitId":552}, {"answerQuestionUserCount":1134,"unitId":1268}]
匿名

发表评论

匿名网友