- SpringBoot多数据源配置
- 1、多套数据源配置
- 1.1、项目目录
- 1.2、配置文件
- 1.3、多数据源配置
- 1.3.1、主数据源配置
- 1.3.2、从数据源配置
- 2、优缺点
- 2.1、优点
- 2.2、缺点
1、多套数据源配置
https://github.com/zhengguofeng1998/DynamicDataSource/tree/master/FirstDemo
1.1、项目目录[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-leob8Z79-1650444395298)(C:UsersZhaLeMaoDeMaoAppDataRoamingTyporatypora-user-imagesimage-20220420162958519.png)]
1.2、配置文件server:
port: 1815
spring:
datasource:
primary:
url: jdbc:mysql://localhost:3306/seata_account?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
driver-class-name: org.gjt.mm.mysql.Driver
slave:
url: jdbc:mysql://localhost:3306/seata_order?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
driver-class-name: org.gjt.mm.mysql.Driver
application:
name: basic-multi-datasource
1.3、多数据源配置
1.3.1、主数据源配置
@Configuration
@MapperScan(basePackages = "com.zgf.springcloud.mapper.primary", sqlSessionFactoryRef = "primaryDataSource")
public class PrimaryDataSourceConfig {
@Bean("primary")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DruidDataSource druidDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setInitialSize(0);
druidDataSource.setMaxActive(180);
druidDataSource.setMaxWait(60000);
druidDataSource.setMinIdle(0);
druidDataSource.setValidationQuery("Select 1 from DUAL");
druidDataSource.setTestOnBorrow(false);
druidDataSource.setTestOnReturn(false);
druidDataSource.setTestWhileIdle(true);
druidDataSource.setTimeBetweenEvictionRunsMillis(60000);
druidDataSource.setMinEvictableIdleTimeMillis(25200000);
druidDataSource.setRemoveAbandoned(true);
druidDataSource.setRemoveAbandonedTimeout(1800);
druidDataSource.setLogAbandoned(true);
return druidDataSource;
}
@Bean
public SqlSessionFactory primaryDataSource(@Qualifier("primary") DruidDataSource druidDataSource) throws Exception {
// 设置数据源
MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
mybatisSqlSessionFactoryBean.setDataSource(druidDataSource);
//mapper的xml文件位置
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
String locationPattern = "classpath*:/mapper/primary/*.xml";
mybatisSqlSessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
//对应数据库的entity位置
String typeAliasesPackage = "com.zgf.springcloud.domain.primary";
mybatisSqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
return mybatisSqlSessionFactoryBean.getObject();
}
}
1.3.2、从数据源配置
@Configuration
@MapperScan(basePackages = "com.zgf.springcloud.mapper.slave", sqlSessionFactoryRef = "slaveDataSource")
public class SlaveDataSourceConfig {
@Bean(value = "slave")
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DruidDataSource druidDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setInitialSize(0);
druidDataSource.setMaxActive(180);
druidDataSource.setMaxWait(60000);
druidDataSource.setMinIdle(0);
druidDataSource.setValidationQuery("Select 1 from DUAL");
druidDataSource.setTestOnBorrow(false);
druidDataSource.setTestOnReturn(false);
druidDataSource.setTestWhileIdle(true);
druidDataSource.setTimeBetweenEvictionRunsMillis(60000);
druidDataSource.setMinEvictableIdleTimeMillis(25200000);
druidDataSource.setRemoveAbandoned(true);
druidDataSource.setRemoveAbandonedTimeout(1800);
druidDataSource.setLogAbandoned(true);
return druidDataSource;
}
@Bean
public SqlSessionFactory slaveDataSource(@Qualifier("slave") DruidDataSource druidDataSource) throws Exception {
// 设置数据源
MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
mybatisSqlSessionFactoryBean.setDataSource(druidDataSource);
//mapper的xml文件位置
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
String locationPattern = "classpath*:/mapper/slave/*.xml";
mybatisSqlSessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
//对应数据库的entity位置
String typeAliasesPackage = "com.zgf.springcloud.domain.slave";
mybatisSqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
return mybatisSqlSessionFactoryBean.getObject();
}
}
- 注解 @MapperScan 指定那些包下的 mapper 使用本数据源,并指定使用哪个SqlSessionFactory,注意,此处的 sqlSessionFactoryRef 即本配置中的注入的 SqlSessionFactory。
- 设置指定的数据源,此处是名为 primary的数据源,使用 @Qualifier 指定。
- MyBatis Plus 对应的 Mapper 若有自定义的 mapper.xml, 则使用 setMapperLocations 指定。
- 若需要对实体进行别名处理,则使用 setTypeAliasesPackage 指定。
然后就是正常的controller…dao等,没有区别,唯一需要注意的是mapper.xml的位置要和@MapperScan指定的路径进行对应。
2、优缺点 2.1、优点-
简单、直接:一个库对应一套处理方式,很好理解。
-
符合开闭原则( OCP ):开发的设计模式告诉我们,对扩展开放,对修改关闭,添加多一个数据库,原来的那一套不需要改动,只添加即可。
- 资源浪费:针对每一个数据源写一套操作,连接数据库的资源也是独立的,分别占用同样多的资源。SqlSessionFactory 是一个工厂,建议是使用单例,完全可以重用,不需要建立多个,只需要更改数据源即可,跟多线程,使用线程池减少资源消耗是同一道理。
- 代码冗余:在前面的多数据源配置中可以看出,其实 primary和 slave 的很多操作是一样的,只是改个名称而已,因此会造成代码冗余。
- 缺乏灵活:所有需要使用的地方都需要引入对应的 mapper,对于很多操作,只是选择数据源的不一样,代码逻辑是一致的。另外,对于一主多从的情况,若需要对多个从库进行负载均衡,相对比较麻烦。
改进见后续文章。



