Mapper
Mapper copied to clipboard
SpringBoot + Mybatis + 通用 Mapper 如何配置多数据源?
SpringBoot + Mybatis + 通用 Mapper 如何配置多数据源? 我始终配置不成功 有没有实例项目
创建完DataSource以后,关键是doScan方法,让dataSouce扫描对应的Mapper。 这种方式可以实现的多种情况:
- 不同的表对应不同的数据源
- 相同的表对应不同的数据源
@Configuration
public class SqlSessionFactoryConfiguration implements ResourceLoaderAware, EnvironmentAware, BeanFactoryPostProcessor {
private static final Logger log = LogManager.getLogger(SqlSessionFactoryConfiguration.class);
private Environment environment;
private ResourceLoader resourceLoader;
public SqlSessionFactoryConfiguration() {
}
private void doScan(BeanDefinitionRegistry registry, String sqlStringFactory, String... basePackage) {
ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
scanner.setMapperProperties(this.environment);
scanner.setSqlSessionFactoryBeanName(sqlStringFactory);
scanner.setResourceLoader(this.resourceLoader);
scanner.registerFilters();
scanner.doScan(basePackage);
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
try {
SqlSessionFactoryProperties sqlSessionFactoryProperties = (SqlSessionFactoryProperties)SpringBootBindUtil.bind(this.environment, SqlSessionFactoryProperties.class, "jdbc");
Map<String, DatasourceConfiguration> configuration = sqlSessionFactoryProperties.getConfig();
if (configuration != null) {
MybatisProperties mybatisProperties = (MybatisProperties)SpringBootBindUtil.bind(this.environment, MybatisProperties.class, "mybatis");
DefaultListableBeanFactory register = (DefaultListableBeanFactory)beanFactory;
BeanDefiner beanDefiner = new BeanDefiner(register);
configuration.forEach((k, v) -> {
Assert.notEmpty(v.getDataSource(), "datasource shall not be null");
Assert.notEmpty(v.getBasePackages(), "basePackages shall not be null");
Assert.hasLength(v.getDefaultClusterName(), "clusterName shall not be null");
DynamicRoutingDataSource dynamicRoutingDataSource = DataSourceFactory.createDynamicRoutingDataSource(v.getDefaultClusterName(), v.getDataSource());
beanDefiner.registerDataSource(k, dynamicRoutingDataSource);
String transactionManagerBeanName = beanDefiner.registerTransactionManager(k, this.transactionManager(dynamicRoutingDataSource));
if (v.getTransactionServicePackages() != null) {
String[] var8 = v.getTransactionServicePackages();
int var9 = var8.length;
for(int var10 = 0; var10 < var9; ++var10) {
String packageName = var8[var10];
log.debug("register transaction manager name:{},{}", packageName, transactionManagerBeanName);
CustomizedTransactionInterceptor.putTransactionManagerName(packageName, transactionManagerBeanName);
}
}
SqlSessionFactory sqlSessionFactory = this.sqlSessionFactory(k, dynamicRoutingDataSource, mybatisProperties);
String factory = beanDefiner.registerSqlSessionFactory(k, sqlSessionFactory);
beanDefiner.registerSqlSessionTemplate(k, this.sqlSessionTemplate(sqlSessionFactory));
this.doScan(register, factory, v.getBasePackages());
});
BeanFactoryTransactionAttributeSourceAdvisor advisor = (BeanFactoryTransactionAttributeSourceAdvisor)register.getBean(BeanFactoryTransactionAttributeSourceAdvisor.class);
CustomizedTransactionInterceptor interceptor = new CustomizedTransactionInterceptor();
register.registerBeanDefinition("transactionInterceptor", BeanDefinitionBuilder.genericBeanDefinition(CustomizedTransactionInterceptor.class, () -> {
return interceptor;
}).setRole(2).getBeanDefinition());
interceptor.setTransactionAttributeSource((TransactionAttributeSource)register.getBean(TransactionAttributeSource.class));
advisor.setAdvice(interceptor);
}
} catch (BeansException var9) {
log.error("catch Exception {} while initiate sqlSessionFactory", var9.getLocalizedMessage(), var9);
throw var9;
} catch (Exception var10) {
log.error("catch Exception {} while initiate sqlSessionFactory", var10.getLocalizedMessage(), var10);
throw new BeanCreationException("initiate error " + var10.getLocalizedMessage(), var10);
}
}
public void setEnvironment(Environment environment) {
this.environment = environment;
}
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
private SqlSessionFactory sqlSessionFactory(String k, DataSource dataSource, MybatisProperties properties) {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setVfs(SpringBootVFS.class);
if (StringUtils.hasText(properties.getConfigLocation())) {
factory.setConfigLocation(this.resourceLoader.getResource(properties.getConfigLocation()));
}
Properties configurationProperties = properties.getConfigurationProperties();
if (configurationProperties != null) {
factory.setConfigurationProperties(configurationProperties);
}
String typeAliasesPackage = properties.getTypeAliasesPackage();
if (StringUtils.hasLength(typeAliasesPackage)) {
factory.setTypeAliasesPackage(typeAliasesPackage);
}
if (properties.getTypeAliasesSuperType() != null) {
factory.setTypeAliasesSuperType(properties.getTypeAliasesSuperType());
}
if (StringUtils.hasLength(properties.getTypeHandlersPackage())) {
factory.setTypeHandlersPackage(properties.getTypeHandlersPackage());
}
if (!ObjectUtils.isEmpty(properties.resolveMapperLocations())) {
factory.setMapperLocations(properties.resolveMapperLocations());
}
try {
return factory.getObject();
} catch (Exception var8) {
throw new RuntimeException(var8);
}
}
private SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
return sqlSessionTemplate;
}
private DataSourceTransactionManager transactionManager(DataSource dataSource) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
return transactionManager;
}
}
师兄,可否提供具体的demo,供参考
253286440