切换主从数据源是在Spring Boot中进行多数据源配置的一项重要任务。通过切换主从数据源,可以实现读写分离和负载均衡的效果,提高系统的性能和稳定性。本文将介绍如何在Spring Boot中实现主从数据源的切换。

1. 引入相关依赖

在Spring Boot项目的pom.xml文件中,需要引入相关的依赖。具体的依赖项根据你使用的数据库决定。以MySQL为例,需要引入如下依赖:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

2. 配置数据源

在application.properties或application.yaml文件中,配置主数据库和从数据库的连接信息。例如:

spring.datasource.master.url=jdbc:mysql://localhost:3306/master
spring.datasource.master.username=root
spring.datasource.master.password=123456

spring.datasource.slave.url=jdbc:mysql://localhost:3306/slave
spring.datasource.slave.username=root
spring.datasource.slave.password=123456

3. 创建数据源配置类

在Spring Boot项目中,需要创建两个数据源配置类分别对应主数据库和从数据库。可以通过@Configuration注解将这两个配置类定义为Bean,并使用@Primary注解指定主数据库。

在主数据库的配置类中,需要定义DataSource和EntityManagerFactory。具体代码如下所示:

@Configuration
public class MasterDataSourceConfig {

    @Primary
    @Bean(name = "masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "masterEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            EntityManagerFactoryBuilder builder, @Qualifier("masterDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.demo.master.entity")
                .persistenceUnit("master")
                .build();
    }
}

在从数据库的配置类中,需要同样地定义DataSource和EntityManagerFactory。具体代码如下所示:

@Configuration
public class SlaveDataSourceConfig {

    @Bean(name = "slaveDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "slaveEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            EntityManagerFactoryBuilder builder, @Qualifier("slaveDataSource") DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.demo.slave.entity")
                .persistenceUnit("slave")
                .build();
    }
}

4. 配置事务管理器

为了使用多数据源,还需要配置事务管理器。在主数据库和从数据库的配置类中,分别定义事务管理器。

在主数据库的配置类中,需要定义主数据库的事务管理器。具体代码如下所示:

@Configuration
@EnableTransactionManagement
public class MasterDataSourceConfig {

    // 省略其他配置

    @Primary
    @Bean(name = "masterTransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("masterEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

在从数据库的配置类中,需要定义从数据库的事务管理器。具体代码如下所示:

@Configuration
@EnableTransactionManagement
public class SlaveDataSourceConfig {

    // 省略其他配置

    @Bean(name = "slaveTransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("slaveEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

至此,主从数据源的切换配置就完成了。在需要切换数据源的地方,可以通过使用@Transactional注解来指定使用哪个数据源。例如:

@Service
public class UserService {

    private final UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional("masterTransactionManager")
    public void saveUser(User user) {
        userRepository.save(user);
    }

    @Transactional("slaveTransactionManager")
    public List getAllUsers() {
        return userRepository.findAll();
    }
}

在上述代码中,saveUser方法使用了主数据源,getAllUsers方法使用了从数据源。通过指定不同的事务管理器,可以方便地切换数据源。