接下来我将为您详细讲解“Spring Boot 优雅整合多数据源”的完整攻略。
一、前置知识
在学习 Spring Boot 优雅整合多数据源之前,需要掌握以下知识点:
- Spring Boot 和 Spring Data JPA 的基础知识。
- 数据库连接池的使用,例如 HikariCP、Druid 等。
- 多数据源的基本概念。
二、多数据源的基本概念
在 Spring Boot 应用中使用多个数据源,可以实现不同的数据源之间的隔离,保证系统的稳定性和安全性。多数据源的基本概念包括以下几点:
- 每个数据源都应该有自己的 DataSource。
- 每个数据源都应该有自己的事务管理器。
- 数据源的配置信息可以通过配置文件或者代码方式进行配置。
三、多数据源的整合
在 Spring Boot 应用中,实现多数据源的整合需要经过以下几个步骤:
- 配置多个数据源的配置信息。
- 配置多个 DataSource 和事务管理器。
- 配置多个 JPA EntityManager 工厂。
- 在项目中按需注入不同的 EntityManager,实现多数据源切换。
四、示例说明
下面通过两个示例来说明 Spring Boot 优雅整合多数据源的具体实现。
示例一:基于注解的多数据源实现
1. 配置多个数据源的配置信息
首先需要在 application.yml
配置文件中添加多个数据源的配置信息,例如:
# 主数据源配置
spring:
datasource:
primary:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test1?serverTimezone=UTC&characterEncoding=UTF-8
username: root
password: root123
# 从数据源配置
secondary:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&characterEncoding=UTF-8
username: root
password: root123
2. 配置多个 DataSource 和事务管理器
可以使用 @Bean
注解在代码中手动配置多个 DataSource 和事务管理器,例如:
@Configuration
public class DataSourceConfig {
// 主数据源配置
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
// 从数据源配置
@Bean(name = "secondaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
// 主数据源事务管理器
@Bean(name = "primaryTransactionManager")
@Primary
public PlatformTransactionManager primaryTransactionManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
// 从数据源事务管理器
@Bean(name = "secondaryTransactionManager")
public PlatformTransactionManager secondaryTransactionManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
3. 配置多个 JPA EntityManager 工厂
在 application.yml
配置文件中添加 JPA 相关配置信息,例如:
# JPA 配置
spring:
jpa:
hibernate:
ddl-auto: update
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
show-sql: true
同时,可以手动配置多个 EntityManager 工厂,例如:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "primaryEntityManagerFactory",
transactionManagerRef = "primaryTransactionManager",
basePackages = {"com.example.demo1.repository"})
public class PrimaryConfig {
@Primary
@Bean(name = "primaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("primaryDataSource") DataSource dataSource) {
return builder
.dataSource(dataSource)
.packages("com.example.demo1.entity")
.persistenceUnit("primary")
.build();
}
@Primary
@Bean(name = "primaryJdbcTemplate")
public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
4. 实现多数据源切换
在项目中按需注入不同的 EntityManager,实现多数据源切换。例如:
@Service
public class UserService {
@PersistenceContext(unitName = "primary")
private EntityManager primaryEntityManager;
@PersistenceContext(unitName = "secondary")
private EntityManager secondaryEntityManager;
public void test() {
// 使用主数据源
primaryEntityManager.createQuery("select ... from UserInfo").getResultList();
// 使用从数据源
secondaryEntityManager.createQuery("select ... from UserInfo").getResultList();
}
}
示例二:基于 AOP 的多数据源实现
1. 配置多个数据源的配置信息
同示例一。
2. 配置多个 DataSource 和事务管理器
同示例一。
3. 配置多个 JPA EntityManager 工厂
同示例一,不过需要将 entityManagerFactoryRef
和 transactionManagerRef
的 value 修改为 "secondary"
。
4. 实现多数据源切换
通过 AOP 实现多数据源切换。例如:
@Aspect
@Component
public class DynamicDataSourceAspect {
@Pointcut("@within(com.example.demo2.annotation.ReadOnly) || @annotation(com.example.demo2.annotation.ReadOnly)")
public void switchDataSource() {}
@Around("switchDataSource()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
ReadOnly readOnly = method.getAnnotation(ReadOnly.class);
if (readOnly == null) {
readOnly = joinPoint.getTarget().getClass().getAnnotation(ReadOnly.class);
}
if (readOnly != null) {
DynamicDataSourceContextHolder.setDataSourceKey("secondary");
}
try {
return joinPoint.proceed();
} finally {
DynamicDataSourceContextHolder.clearDataSourceKey();
}
}
}
同时,在需要使用从数据源的方法上添加 @ReadOnly
注解,例如:
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@ReadOnly
public List<UserInfo> listUsers() {
return userRepository.findAll();
}
}
结语
通过以上示例可以看到,Spring Boot 优雅整合多数据源并不难,只需要在不同的层面进行适当的配置和切换,即可实现多数据源的灵活应用。希望这篇文章对大家有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot 优雅整合多数据源 - Python技术站