多平台统一管理软件接口,如何实现多平台统一管理软件接口
257
2022-12-10
springboot2+mybatis多种方式实现多数据配置方法
业务系统复杂程度增加,为了解决数据库I/O瓶颈,很自然会进行拆库拆表分服务来应对。这就会出现一个系统中可能会访问多处数据库,需要配置多个数据源。
第一种场景:项目服务从其它多处数据库取基础数据进行业务处理,因此各库之间不会出现重表等情况。
第二种场景:为了减轻写入压力进行读写分库,读走从库,写为主库。此种表名等信息皆为一致。
第三种场景:以上两种皆有。对于某些业务需要大数据量的汇总统计,希望不影响正常业务必须走从库(表信息一致),某些配置信息不存在读写压力,出现不分库(表信息不一致)
项目源代码:
https://github.com/zzsong/springboot-multiple-datasource.git
有三个目录:
one:
直接使用多@Bean配置,@MapperScan来路径区分读何库
two:
使用注解的方式来标识走何dataSource,AOP拦截注入动态数据源
third:
使用spring的Bean命名策略进行区分数据来源
项目技术选型: springBoot2.2.5 + mybatis + druid + mysql
先看主要的pom包
application.yml
spring:
datasource:
druid:
core:
url: jdbc:mysql:///kc_core?characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
schedule:
url: jdbc:mysql:///kc_schedule?characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
mysql新版本必须带有serverTimezone,不然会报连接异常。
第一种:通过@MapperScans 扫描匹配相关的数据源
@Configuration
@MapperScans({
@MapperScan(basePackages = "com.zss.one.mapper.core", sqlSessionTemplateRef = "coreSqlSessionTemplate",sqlSessionFactoryRef = "coreSqlSessionFactory"),
@MapperScan(basePackages = "com.zss.one.mapper.schedule", sqlSessionTemplateRef = "scheduleSqlSessionTemplate",sqlSessionFactoryRef = "scheduleSqlSessionFactory")
})
public class MybatisOneConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.druid.core")
public DataSource coreDataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean
public SqlSessionFactory coreSqlSessionFactory(@Qualifier("coreDataSource") DataSource coreDataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(coreDataSource);
sessionFactory.getObject().getConfiguration().setJdbcTypeForNull(null);
sessionFactory.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
return sessionFactory.getObject();
}
@Bean
public SqlSessionTemplate coreSqlSessionTemplate(@Qualifier("coreSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
http:// return new SqlSessionTemplate(sqlSessionFactory);
}
//======schedule=http://=======
@Bean
@ConfigurationProperties(prefix = "spring.datasource.druid.schedule")
public DataSource scheduleDataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean
public SqlSessionFactory scheduleSqlSessionFactory(@Qualifier("scheduleDataSource") DataSource coreDataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(coreDataSource);
sessionFactory.getObject().getConfiguration().setJdbcTypeForNull(null);
sessionFactory.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
return sessionFactory.getObject();
}
@Bean
public SqlSessionTemplate scheduleSqlSessionTemplate(@Qualifier("scheduleSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
第二种是动态数据源模式,通过AOP切入注解引导使用何数据源。用自定义注解@interface来标识方法走对应的数据源。
注意事项:类中的方法再调用带数据源的方法,不能被AOP切入
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TargetDataSource {
String value();
}
extends spring的动态DataSource路由来匹配
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextRouting.getDataSourceName();
}
}
@Configuration
//@EnableConfigurationProperties(MybatisProperties.class)//不要使用此公共配置,Configuration会破坏相关dataSource的配置
@MapperScan("com.zss.two.mapper")
public class MybatisConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.druid.core")
public DataSource coreDataSource() {
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.druid.schedule")
public DataSource scheduleDataSource() {
return DruidDataSourceBuilder.create().build();
}
@Autowired
@Qualifier("coreDataSource")
private DataSource coreDataSource;
@Autowired
@Qualifier("scheduleDataSource")
private DataSource scheduleDataSource;
@Bean
public DynamicDataSource dataSource() {
Map
targetDataSources.put(DataSourceConstants.CORE_DATA_SOURCE, coreDataSource);
targetDataSources.put(DataSourceConstants.SCHEDULE_DATA_SOURCE, scheduleDataSource);
DynamicDataSource dataSource = new DynamicDataSource();
//设置数据源映射
dataSource.setTargetDataSources(targetDataSources);
//// 设置默认数据源,当无法映射到数据源时会使用默认数据源
dataSource.setDefaultTargetDataSource(coreDataSource);
dataSource.afterPropertiesSet();
return dataSource;
}
/**
* 根据数据源创建SqlSessionFactory
*/
@Bean
public SqlSessionFactory sqlSessionFactory(DynamicDataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.getObject().getConfiguration().setJdbcTypeForNull(null);
sessionFactory.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
return sessionFactory.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
第三种,自定义Bean命名策略,按beanName进行自动匹配使用数据源
@Component
public class CoreBeanNameGenerator implements BeanNameGenerator {
@Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
return "core"+ ClassUtils.getShortName(definition.getBeanClassName());
}
}
@Component
public class ScheduleBeanNameGenerator implements BeanNameGenerator {
@Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
return "schedule"+ ClassUtils.getShortName(definition.getBeanClassName());
}
}
使用mybatis MapperScannerConfigurer自动扫描,将Mapper接口生成注入到spring
@Bean
public MapperScannerConfigurer coreMapperScannerConfig(CoreBeanNameGenerator coreBeanNameGenerator){
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setNameGenerator(coreBeanNameGenerator);
configurer.setBasePackage("com.zss.third.mapper.core,com.zss.third.mapper.order");
configurer.setSqlSessionFactoryBeanName("coreSqlSessionFactory");
configurer.setSqlSessionTemplateBeanName("coreSqlSessionTemplate");
return configurer;
}
@Bean
public MapperScannerConfigurer scheduleMapperScannerConfig(ScheduleBeanNameGenerator scheduleBeanNameGenerator){
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setNameGenerator(scheduleBeanNameGenerator);
configurer.setBasePackage("com.zss.third.mapper.schedule,com.zss.third.mapper.order");
configurer.setSqlSessionFactoryBeanName("scheduleSqlSessionFactory");
configurer.setSqlSessionTemplateBeanName("scheduleSqlSessionTemplate");
return configurer;
}
到此,三种多数据源匹配主要点介绍完,详细直接下载github项目。 在resources/db含有相关测试表及数据脚本。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~