所谓多数据源,就是一个项目中采用了不同数据库实例中的多个库,或者同一个数据库实例中多个不同的库。比如实现数据库读写分离、分库分表、备份等操作。
JdbcTemplate多数据源的配置是比较简单的,因为一个JdbcTemplate对应一个DataSource,开发者只需要手动提供多个DataSource,再手动配置JdbcTemplate即可。
JPA多数据源的配置需要指定对应的Entity实体和Repository定义的位置,用@Primary来区分主数据源。
一、配置yml文件
server:
port: 8080
spring:
# 数据库配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource
first: #这里是数据库一
url: jdbc:sqlserver://localhost:1433;DatabaseName=name1
username: ***
password: ***
second: #这里是数据库二
url: jdbc:sqlserver://localhost:1433;DatabaseName=name2
username: ***
password: ***
pom.xml 添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
二、创建数据源配置类 DatasourceConfig .class
定义两个DataSource来读取application.yml中的不同配置。
@Configuration
public class DataSourceConfig {
@Primary //标记一个主数据库
@Bean(name = "firstDataSource")
@Qualifier("firstDataSource")
@ConfigurationProperties(prefix = "spring.datasource.first")
public DruidDataSource firstDataSource() {
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "secondDataSource")
@Qualifier("secondDataSource")
@ConfigurationProperties(prefix="spring.datasource.second")
public DruidDataSource secondDataSource() {
return DruidDataSourceBuilder.create().build();
}
}
三、配置 JdbcTemplate Config 或JPA Config
1. 配置 JdbcTemplateConfig
(1)项目只要引入了 spring-jdbc 依赖,如果开发者没有提供 JdbcTemplate 实例时,Spring Boot 默认会提供一个 JdbcTemplate 实例。
(2)如果配置多数据源时,由开发者自己提供 JdbcTemplate 实例,代码如下:
JdbcTemplateConfig .class
@Configuration
public class JdbcTemplateConfig {
@Primary
@Bean("firstJdbcTemplate")
public JdbcTemplate firstJdbcTemplate(@Qualifier("firstDataSource")DataSource dataSource){
return new JdbcTemplate(dataSource);
}
@Bean("secondJdbcTemplate")
public JdbcTemplate secondJdbcTemplate(@Qualifier("secondDataSource")DataSource dataSource){
return new JdbcTemplate(dataSource);
}
}
2. 配置 JPA Config
JPA指定数据源需要指定对应的Entity实体和Repository定义的位置,用@Primary来区分主数据源。
(1)first数据源的JPA配置 (FirstDataBaseConfig.class)
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
// 配置连接工厂
entityManagerFactoryRef = "firstFactory",
// 配置事物管理器
transactionManagerRef = "firstTransaction",
// 设置Jpa first数据源的 repository所在位置
basePackages = {"com.xx.xx.xx.**.repository"} //修改这里
)
public class FirstDataBaseConfig {
@Autowired
@Qualifier("firstDataSource") //修改这里
private DataSource firstDataSource;
@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties properties;
// 以下是jpa的配置
/**
* 连接工厂
* @param builder 创建工具
* @return 结果
*/
@Primary
@Bean(name = "firstFactory")
public LocalContainerEntityManagerFactoryBean firstFactory(EntityManagerFactoryBuilder builder) {
return builder
// 设置数据源
.dataSource(firstDataSource)
//设置实体类所在位置.扫描所有带有 @Entity 注解的类
.packages("xx.xx.xx.first.**.entity") //修改这里
// Spring会将EntityManagerFactory注入到Repository之中.有了 EntityManagerFactory之后,
// Repository就能用它来创建 EntityManager 了,然后 EntityManager 就可以针对数据库执行操作
.persistenceUnit("first")
// 为了加载yml中jpa下hibernate的相关配置
.properties(properties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings()))
.build();
}
/**
* 配置事物管理器
*
* @param builder 创建工具
* @return 结果
*/
@Primary
@Bean(name = "firstTransaction")
PlatformTransactionManager firstTransaction(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(Objects.requireNonNull(firstFactory(builder).getObject()));
}
(2)second数据源的JPA配置( SecondDataBaseConfig.class)
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
// 配置连接工厂
entityManagerFactoryRef = "secondFactory",
// 配置事物管理器
transactionManagerRef = "secondTransaction",
// 设置Jpa second数据源的 repository所在位置
basePackages = {"com.xx.xx.xx.**.repository"} //修改这里
)
public class SecondDataBaseConfig {
@Autowired
@Qualifier("secondDataSource") //修改这里
private DataSource secondDataSource;
@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties properties;
// 以下是jpa的配置
/**
* 连接工厂
* @param builder 创建工具
* @return 结果
*/
@Bean(name = "secondFactory")
public LocalContainerEntityManagerFactoryBean secondFactory(EntityManagerFactoryBuilder builder) {
return builder
// 设置数据源
.dataSource(secondDataSource)
//设置实体类所在位置.扫描所有带有 @Entity 注解的类
.packages("xx.xx.xx.second.**.entity") //修改这里
// Spring会将EntityManagerFactory注入到Repository之中.有了 EntityManagerFactory之后,
// Repository就能用它来创建 EntityManager 了,然后 EntityManager 就可以针对数据库执行操作
.persistenceUnit("second")
// 为了加载yml中jpa下hibernate的相关配置
.properties(properties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings()))
.build();
}
/**
* 配置事物管理器
*
* @param builder 创建工具
* @return 结果
*/
@Bean(name = "secondTransaction")
PlatformTransactionManager secondTransaction(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(Objects.requireNonNull(secondFactory(builder).getObject()));
}
四、实例化使用
(1)JdbcTemplate实例化
@RestController
public class Controller {
@Resource(name = "firstJdbcTemplate")
private JdbcTemplate firstJdbcTemplate;
@Resource(name = "secondJdbcTemplate")
private JdbcTemplate secondJdbcTemplate;
@PostMapping("/testSave")
public String test(){
// SQL查询数据库1
String SQL1 = "SELECT * FROM dataBaseName1";
List<> list1 = firstJdbcTemplate.queryForList(SQL1);
// SQL查询数据库2
String SQL2 = "SELECT * FROM dataBaseName2";
List<> list2 = secondJdbcTemplate.queryForList(SQL2);
}
}
(2)JPA只需要将不同数据源的Entity实体和Repository定义放到对应的位置,直接使用。