实际的业务场景中,有时需要使用多数据源,我们看看如何快速地进行配置。
基础环境
Spring boot 2.1.1.RELEASE
Mybatis 1.3.1
HikariCP 3.1.0
pom文件
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
主要配置
1 application.properties
spring.datasource.primary.jdbc-url=url1
spring.datasource.primary.username=usr1
spring.datasource.primary.password=pw1
spring.datasource.schema.jdbc-url=url2
spring.datasource.schema.username=usr2
spring.datasource.schema.password=pw2
注意配置多数据源时,url的key需要配置成jdbc-url
2 数据库连接池配置类
DatabaseConfiguration.java
用于使用不同url连接池的实例化
@Configuration
public class DatabaseConfiguration {
public static final String PRIMARY_DATASOURCE = "PriDS";
public static final String METADATA_DATASOURCE = "MetaDS";
@Bean(name = PRIMARY_DATASOURCE, destroyMethod = "")
@ConfigurationProperties(prefix = "spring.datasource.primary")
@Primary
public DataSource dataSourcePrimary(){
return new HikariDataSource();
}
@Bean(name = METADATA_DATASOURCE, destroyMethod = "")
@ConfigurationProperties(prefix = "spring.datasource.schema")
public DataSource dataSourceMetadata(){
return new HikariDataSource();
}
}
3 创建Mybatis mapper bean配置类
MyBatisConfiguration.java
@Configuration
@MapperScan("com.example.multiDatasourceDemo.mapper")
public class MyBatisConfiguration {
public static final String PRIMARY_SESSION_FACTORY = "primarySessionFactory";
public static final String METADATA_SESSION_FACTORY = "metadataSessionFactory";
/*primary datasource factory bean,use @MapperScan for creating mapper bean */
@Bean(name = PRIMARY_SESSION_FACTORY)
@Primary
public SqlSessionFactoryBean primarySqlSessionFactory(
@Named(DatabaseConfiguration.PRIMARY_DATASOURCE)final DataSource primaryDataSource) throws Exception{
final SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(primaryDataSource);
VFS.addImplClass(SpringBootVFS.class);
PathMatchingResourcePatternResolver pathM3R = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(pathM3R.getResources("classpath:mapper/**/*Mapper.xml"));
sqlSessionFactoryBean.setTypeAliasesPackage("com.example.multiDatasourceDemo.domain");
SqlSessionFactory sqlSessionFactory;
sqlSessionFactory = sqlSessionFactoryBean.getObject();
return sqlSessionFactoryBean;
}
/*another datasource factory bean*/
@Bean(name = METADATA_SESSION_FACTORY)
public SqlSessionFactoryBean metaSqlSessionFactory(
@Named(DatabaseConfiguration.METADATA_DATASOURCE) final DataSource anotherDataSource) throws Exception {
final SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(anotherDataSource);
VFS.addImplClass(SpringBootVFS.class);
PathMatchingResourcePatternResolver pathM3R = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(pathM3R.getResources("classpath:anothermapper/anotherMapper.xml"));
sqlSessionFactoryBean.setTypeAliasesPackage("com.example.multiDatasourceDemo.domain");
final SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject();
return sqlSessionFactoryBean;
}
@Bean
public MapperFactoryBean<AnotherMapper> dbMapper(
@Named(METADATA_SESSION_FACTORY) final SqlSessionFactoryBean sqlSessionFactoryBean) throws Exception {
MapperFactoryBean<AnotherMapper> factoryBean = new MapperFactoryBean<>(AnotherMapper.class);
factoryBean.setSqlSessionFactory(sqlSessionFactoryBean.getObject());
return factoryBean;
}
}
创建两个使用不同连接池的工厂bean,作用是通以此创建mapper bean。其中primaryDataSource使用了@MapperScan注解进行mapper class的扫描,在需要被扫描的mapper class上添加@Mapper注解。在项目中mapper数量较多的情况下使用此方式,减少手动创建的代码量。anotherDataSource实例化的mapper使用手动创建的方式,即dbMapper方法,指定了mapper class。
此外如果sql在xml文件内,需要配置setMapperLocations,将xml文件路径配置成要扫描的内容。
setTypeAliasesPackage用于配置sql中使用的resultType当参数的类的包路径,配置后使用时只需要写类名即可。否则需要写完整的包路径和类名。当整个项目打包jar文件后,setTypeAliasesPackage配置不生效,导致部分类扫描不到,需要添加VFS.addImplClass(SpringBootVFS.class)配置。
4 使用实例
详见github的项目,包含测试的controller、mapper、sql与测试用例
参考链接https://medium.com/@d.lopez.j...
项目地址
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。