近期在处理项目整合的task,涉及到多数据源配置,现将具体实践分享给大家。
配置多数据源
1.application.yml配置
first:
datasource:
password: *****
url: *****
username: *****
second:
datasource:
password: *****
url: *****
username: *****
2.数据源配置类
项目结构如下:
)
@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}]