Spring Boot多数据源整合

如何用Spring Boot 整合 MyBatis 连接多种数据源 & Spring Data Jpa 如何连接多种数据源

引入依赖项公用

1
2
3
4
5
6
7
dependencies {
compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.1')
compile('org.springframework.boot:spring-boot-starter-web')
runtime('mysql:mysql-connector-java')
runtime('com.microsoft.sqlserver:mssql-jdbc')
testCompile('org.springframework.boot:spring-boot-starter-test')
}

配置数据源公用

新建数据源配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Configuration
public class DataSourceProperties {

@Bean("mysqlDataSource")
@ConfigurationProperties(prefix = "datasource.mysql")

@Primary
public DataSource mysqlDataSource() {
return DataSourceBuilder.create().build();
}

@Bean("mssqlDataSource")
@ConfigurationProperties(prefix = "datasource.mssql")
public DataSource mssqlDataSource(){
return DataSourceBuilder.create().build();
}

}

application.properties配置数据源

1
2
3
4
5
6
7
8
datasource.mysql.url=jdbc:mysql://xx?serverTimezone=Asia/Shanghai&characterEncoding=utf8
datasource.mysql.username=xx
datasource.mysql.password=xx
datasource.mysql.driver-class-name=com.mysql.jdbc.Driver
datasource.mssql.url=jdbc:sqlserver://xx;databasename=xx
datasource.mssql.username=xx
datasource.mssql.password=xx
datasource.mssql.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver

MyBatis配置

mssql配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Configuration
@EnableTransactionManagement
@MapperScan(basePackages = "指定mssql repository包名", sqlSessionFactoryRef = "mssqlSessionFactory")
public class MssqlConfig {
@Autowired
@Qualifier("mssqlDataSource")
private DataSource mssqlDataSource;

@Bean(name = "mssqlTransactionManager")
public DataSourceTransactionManager dataSourceTransactionManager() {
return new DataSourceTransactionManager(mssqlDataSource);
}

@Bean(name = "mssqlSessionFactory")
public SqlSessionFactory clusterSqlSessionFactory() throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(mssqlDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:config/mybatis/mapper/*.xml"));
return sessionFactory.getObject();
}

}

mysql配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Configuration
@EnableTransactionManagement
@MapperScan(basePackages = "指定mysql repository包名", sqlSessionFactoryRef = "mysqlSessionFactory")
public class MySqlConfig {
@Autowired
@Qualifier("mysqlDataSource")
private DataSource mysqlDataSource;

@Bean(name = "mysqlTransactionManager")
@Primary
public DataSourceTransactionManager dataSourceTransactionManager() {
return new DataSourceTransactionManager(mysqlDataSource);
}

@Bean(name = "mysqlSessionFactory")
@Primary
public SqlSessionFactory clusterSqlSessionFactory() throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(mysqlDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:config/mybatis/mapper/*.xml"));
return sessionFactory.getObject();
}
}

Spring Data Jpa配置

mssql配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef="entityManagerFactorySecondary",
transactionManagerRef="transactionManagerSecondary",
basePackages= { "指定mssql repository包名" })
public class MSSqlConfig {
@Autowired
@Qualifier("mssqlDataSource")
private DataSource mssqlDataSource;

@Bean(name = "entityManagerSecondary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactorySecondary(builder).getObject().createEntityManager();
}

@Bean(name = "entityManagerFactorySecondary")
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) {
return builder.dataSource(mssqlDataSource).properties(getVendorProperties(mssqlDataSource))
//设置实体类所在位置
.packages("指定实体路径")
.persistenceUnit("mssqlPersistenceUnit")
.build();
}

@Autowired
private JpaProperties jpaProperties;

private Map getVendorProperties(DataSource dataSource) {
return jpaProperties.getHibernateProperties(dataSource);
}

@Bean(name = "transactionManagerSecondary")
PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}

}

Mysql配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryPrimary",
transactionManagerRef = "transactionManagerPrimary",basePackages = {"指定mysql repository包名"})
public class MySqlConfig {

@Autowired
@Qualifier("mysqlDataSource")
private DataSource mysqlDataSource;

@Primary
@Bean(name = "entityManagerPrimary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
@Primary
@Bean(name = "entityManagerFactoryPrimary")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
return builder.dataSource(mysqlDataSource).properties(getVendorProperties(mysqlDataSource))
//设置实体类所在位置
.packages("指定实体路径")
.persistenceUnit("mysqlPersistenceUnit")
.build();
}
@Autowired
private JpaProperties jpaProperties;

private Map getVendorProperties(DataSource dataSource) {
return jpaProperties.getHibernateProperties(dataSource);
}

@Primary
@Bean(name = "transactionManagerPrimary")
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}

}

关键注解的解析

  1. @Configuration

相当于传统的xml配置文件,项目中如果需要依赖第三方的xml文件,仍然建议通过此配置类作为项目的配置主类,通过@ImportResource注解加载xml配置文件。

  1. @Bean

该注解告诉Spring这个方法将会返回一个对象,该对象要注册为Spring应用上下文中的bean

  1. @ConfigurationProperties

读取配置文件信息,读取并自动封装成实体类。这样在代码里使用更加方便。@Value需要单独建立xxxProperties进行映射,效果差不多

  1. @Primary

当系统里面出现多个数据源的时候,需要进行人为指定主数据源

  1. @EnableTransactionManagement

Spring Boot使用事务非常简单,使用该注解开启事务支持,然后在访问数据库的Service方法上添加注解@Transactional便可。

  1. @MapperScan

在数据持久层使用MyBatis时候,使用该注解配置扫描Mapper位置

  1. @Autowired

使用该注解进行自动注入,但是Spring 容器中匹配候选Bean数目必须有且仅有一个。当找不到一个匹配的时候,Spring容器会抛出异常

  1. @Qualifier

在当使用@Autowired产生歧义的时候,可以使用该注解指定对应的name来消除歧义

  1. EnableJpaRepositories

该注解开启对Spring Data JPA Repository的支持

通过以上的配置,项目就可以同时访问多种数据源了。

赶紧记下,别待会儿忘了