MyBatis下多数据源的配置
多datasource的配置原理:将不同数据源的mapper接口放在不同的包内,再在数据源配置中,用@MapperScan注解扫描不同的包
引言
先来学习一下单数据源情况下的配置原理,只关心多数据源的配置方法的读者可跳过引言
相关依赖
tk.mybatis依赖,com.ly.dal,org.mybatis.spring.boot
@Mapper注解和@MapperScan注解
在配置类上使用@MapperScan注解后,扫描的包内所有接口就默认是mapper接口了,不需要再在每个接口上使用@Mapper注解
SqlSessionFactory 和 SqlSessionTemplate
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1cZqexoJ-1680258376654)(D:\MyConfiguration\zhen.kong\AppData\Roaming\Typora\typora-user-images\image-20221114162938777.png)]
注解方式配置数据源
@ConfigurationProperties(prefix = “spring.datasource”)
为当前注入的bean对象读取配置文件以spring.datasource开头的配置项,如果之后的部分和实体类的属性一致的话,会将配置的内容注入给对象的属性中
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource getDataSource() {
RoutableDataSource ds = new RoutableDataSource();
ds.setEnv(env);
ds.setProjectId(appUk);
ds.setDbName(dbName);
ds.init();
return ds;
}
多数据源的配置方法
流程
- 将不同数据源的mapper接口放在不同的包中
- 创建两个数据源的配置类
- 在controller-service中直接调用mapper接口即可
配置类
核心代码:
- @MapperScan注解修改该数据源扫描的mapper位置,注意,sqlSessionTemplateRef 也一定要配置,否则还是配置的默认sqlSessionTemplate,导致数据源无法切换
@MapperScan(basePackages = "com.ly.pnp.job.mapper",sqlSessionTemplateRef = "ds1SqlSessionTemplate")
- 因为SqlSessionFactory的自动配置已修改为手动配置,所以mapper.xml的扫描路径也一定要手动配置
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapping/*.xml"));
否则会报错:
Invalid bound statement (not found): com.ly.pnp.job.mapper_history.PnpHistoryMovingMapper.selectHistory
DataSource1Config.java
/**
* 主数据源的配置
* @author fsfsefs
* date:2022-11-14
*/
@Configuration
@PropertySource(value = {"classpath:application.yml"})
@MapperScan(basePackages = "com.ly.pnp.job.mapper",sqlSessionTemplateRef = "ds1SqlSessionTemplate")
public class DataSource1Config {
@Value("${env}")
private String env;
@Value("${appUk}")
private String appUk;
@Value("${db.name}")
private String dbName;
// 主数据源的注解@Primary
@Primary
@Bean(name="datasource1")
public DataSource dataSource() {
Logger.info(new Marker("application", "启动", "初始化数据库连接"), "开始初始化数据库连接1,当前环境: "+env);
RoutableDataSource ds = new RoutableDataSource();
ds.setEnv(env);
ds.setProjectId(appUk);
ds.setDbName(dbName);
ds.init();
return ds;
}
@Bean(name="ds1SqlSessionFactory")
public SqlSessionFactory ds1SqlSessionFactory(@Qualifier("datasource1") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean=new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapping/*.xml"));
return bean.getObject();
}
@Bean(name="ds1SqlSessionTemplate")
public SqlSessionTemplate ds1SqlSessionTemplate(@Qualifier("ds1SqlSessionFactory") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
}
DataSource2Config.java
/**
* 数据源2的配置
* @author fsdfdsfs
* date:2022-11-14
*/
@Configuration
@PropertySource(value = {"classpath:application.yml"})
@MapperScan(basePackages = "com.ly.pnp.job.mapper_history",sqlSessionTemplateRef = "ds2SqlSessionTemplate")
public class DataSource2Config {
@Value("${env}")
private String env;
@Value("${appUk}")
private String appUk;
@Value("${db2.name}")
private String db2Name;
@Bean(name="datasource2")
public DataSource dataSource2() {
Logger.info(new Marker("application", "启动", "初始化数据库连接"), "开始初始化数据库连接2,当前环境: "+env);
RoutableDataSource ds = new RoutableDataSource();
ds.setEnv(env);
ds.setProjectId(appUk);
ds.setDbName(db2Name);
ds.init();
return ds;
}
@Bean(name="ds2SqlSessionFactory")
public SqlSessionFactory ds2SqlSessionFactory(@Qualifier("datasource2") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean=new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapping/*.xml"));
return bean.getObject();
}
@Bean(name="ds2SqlSessionTemplate")
public SqlSessionTemplate ds1SqlSessionTemplate(@Qualifier("ds2SqlSessionFactory") SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
}