用Java基于Spring框架搭建一套支持多数据源的web系统框架

在使用Java Spring框架搭建支持多数据源的Web系统框架时,你可以按照以下步骤进行:

步骤一:添加依赖

首先,在pom.xml文件中添加Spring Boot和相关数据库依赖:

<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring Boot Starter Data JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- 数据库驱动依赖,例如MySQL -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
</dependencies>

步骤二:配置多数据源

  1. 创建多个数据源配置类,每个数据源对应一个数据库连接:
  2. @Configuration
    @EnableTransactionManagement
    public class DataSourceConfig {
    
        @Bean(name = "dataSource1")
        @ConfigurationProperties(prefix = "spring.datasource.datasource1")
        public DataSource dataSource1() {
            return DataSourceBuilder.create().build();
        }
    
        @Bean(name = "entityManagerFactory1")
        public LocalContainerEntityManagerFactoryBean entityManagerFactory1(
                EntityManagerFactoryBuilder builder,
                @Qualifier("dataSource1") DataSource dataSource) {
            return builder
                    .dataSource(dataSource)
                    .packages("com.example.domain.datasource1")
                    .persistenceUnit("datasource1")
                    .build();
        }
    
        @Bean(name = "transactionManager1")
        public PlatformTransactionManager transactionManager1(
                @Qualifier("entityManagerFactory1") EntityManagerFactory entityManagerFactory) {
            return new JpaTransactionManager(entityManagerFactory);
        }
    }
    

  3. 配置 application.properties 文件,设置多数据源的连接信息:
    ## 数据源1配置
    spring.datasource.datasource1.url=jdbc:mysql://localhost:3306/db1
    spring.datasource.datasource1.username=root
    spring.datasource.datasource1.password=rootPassword
    spring.datasource.datasource1.driver-class-name=com.mysql.cj.jdbc.Driver
    
    ## 数据源2配置
    spring.datasource.datasource2.url=jdbc:mysql://localhost:3306/db2
    spring.datasource.datasource2.username=root
    spring.datasource.datasource2.password=rootPassword
    spring.datasource.datasource2.driver-class-name=com.mysql.cj.jdbc.Driver
    

    步骤三:定义实体类和Repository

  4. 创建实体类和对应的Repository接口,分别对应不同的数据源。
  5. 步骤四:创建Controller

    编写Controller类,处理业务逻辑,并根据需要调用不同数据源的Repository。

    @Configuration
    public class DataSourceConfig {
    
        @Primary
        @Bean(name = "dataSource1")
        @ConfigurationProperties(prefix = "spring.datasource.datasource1")
        public DataSource dataSource1() {
            return DataSourceBuilder.create().build();
        }
    
        @Bean(name = "entityManagerFactory1")
        public LocalContainerEntityManagerFactoryBean entityManagerFactory1(EntityManagerFactoryBuilder builder,
                                                                           @Qualifier("dataSource1") DataSource dataSource) {
            return builder
                    .dataSource(dataSource)
                    .packages("com.example.entity1")
                    .persistenceUnit("dataSource1")
                    .build();
        }
    
        @Bean(name = "transactionManager1")
        public PlatformTransactionManager transactionManager1(@Qualifier("entityManagerFactory1") EntityManagerFactory entityManagerFactory) {
            return new JpaTransactionManager(entityManagerFactory);
        }
    
        @Bean(name = "dataSource2")
        @ConfigurationProperties(prefix = "spring.datasource.datasource2")
        public DataSource dataSource2() {
            return DataSourceBuilder.create().build();
        }
    
        @Bean(name = "entityManagerFactory2")
        public LocalContainerEntityManagerFactoryBean entityManagerFactory2(EntityManagerFactoryBuilder builder,
                                                                           @Qualifier("dataSource2") DataSource dataSource) {
            return builder
                    .dataSource(dataSource)
                    .packages("com.example.entity2")
                    .persistenceUnit("dataSource2")
                    .build();
        }
    
        @Bean(name = "transactionManager2")
        public PlatformTransactionManager transactionManager2(@Qualifier("entityManagerFactory2") EntityManagerFactory entityManagerFactory) {
            return new JpaTransactionManager(entityManagerFactory);
        }
    }
    

    在这段代码中,我们配置了两个数据源(dataSource1dataSource2),每个数据源都有对应的实体管理工厂(entityManagerFactory1entityManagerFactory2)以及事务管理器(transactionManager1transactionManager2)。

    步骤五:使用多数据源

    在服务或业务逻辑中,根据需要使用不同的数据源。可以通过在Repository中指定数据源的方式来实现:

    @Repository
    public interface UserRepository extends JpaRepository<User, Long> {
        // 使用第一个数据源
    }
    
    @Repository
    public interface ProductRepository extends JpaRepository<Product, Long> {
        // 使用第二个数据源
    }
    

    步骤六:配置多数据源交换

    在需要切换数据源的地方,可以使用@Primary@Qualifier注解来指定使用哪个数据源。比如在Service层或Controller层中:

    @Service
    public class UserService {
        
        @Autowired
        @Qualifier("userRepository")
        private UserRepository userRepository;
    
        // 使用第一个数据源的Repository操作数据
    }
    
    @Service
    public class ProductService {
    
        @Autowired
        @Qualifier("productRepository")
        private ProductRepository productRepository;
    
        // 使用第二个数据源的Repository操作数据
    }
    

    步骤七:测试多数据源功能

    最后,通过编写测试用例来验证多数据源的功能是否正常工作。可以分别测试不同数据源的读写操作,以确保整个系统的多数据源支持已经成功搭建。在这段代码中,我们使用了@EnableJpaRepositories注解分别为两个数据源配置了不同的JpaRepository包路径、实体管理工厂引用和事务管理器引用。这样就可以确保每个数据源的JpaRepository都能正确地与对应的实体管理工厂和事务管理器关联起来。

    @EnableJpaRepositories(
            basePackages = "com.example.repository1",
            entityManagerFactoryRef = "entityManagerFactory1",
            transactionManagerRef = "transactionManager1"
    )
    public class DataSource1JpaConfig {
        // 这里配置针对dataSource1的JpaRepository
    }
    
    @EnableJpaRepositories(
            basePackages = "com.example.repository2",
            entityManagerFactoryRef = "entityManagerFactory2",
            transactionManagerRef = "transactionManager2"
    )
    public class DataSource2JpaConfig {
        // 这里配置针对dataSource2的JpaRepository
    }
    

    当需要在多数据源环境下执行事务管理时,需要进行额外的配置以确保事务能够正确地跨多个数据源进行管理。

    步骤八:配置多数据源事务管理

  6. 创建一个事务管理器工厂类,用于创建支持多数据源的事务管理器:
    @Configuration
    public class TransactionManagerConfig {
    
        @Bean
        @Primary
        public PlatformTransactionManager transactionManager(
                @Qualifier("dataSource1TransactionManager") PlatformTransactionManager dataSource1TransactionManager,
                @Qualifier("dataSource2TransactionManager") PlatformTransactionManager dataSource2TransactionManager) {
            ChainedTransactionManager transactionManager = new ChainedTransactionManager(
                    dataSource1TransactionManager, dataSource2TransactionManager);
            return transactionManager;
        }
    }
    
  7. 在需要进行事务管理的Service方法上添加 @Transactional 注解,以确保事务能够正确地跨多个数据源进行管理。
    @Service
    public class MultiDataSourceService {
    
        @Autowired
        private UserRepository userRepository;
    
        @Autowired
        private ProductRepository productRepository;
    
        @Transactional(transactionManager = "transactionManager")
        public void transferBetweenDataSources(User user, Product product) {
            // 在此方法中进行跨数据源的业务操作
            userRepository.save(user);
            productRepository.save(product);
        }
    }
    

    步骤九:测试多数据源事务管理

    编写测试用例来验证多数据源事务管理的功能是否正常工作。可以模拟跨数据源的业务操作,并验证事务是否能够正确地回滚或提交。

    @Service
    public class MultiDataSourceService {
    
        @Autowired
        private UserRepository userRepository;
    
        @Autowired
        private ProductRepository productRepository;
    
        @Transactional(transactionManager = "transactionManager")
        public void transferBetweenDataSources(User user, Product product) {
            // 在第一个数据源保存用户信息
            userRepository.save(user);
    
            // 模拟异常情况,使第二个数据源保存产品信息时出现错误
            if (product.getName().equals("error")) {
                throw new RuntimeException("Error occurred while saving product");
            }
    
            // 在第二个数据源保存产品信息
            productRepository.save(product);
        }
    }
    

    在这段代码中,我们定义了一个MultiDataSourceService服务类,其中的transferBetweenDataSources方法模拟了一个跨数据源的业务操作:先在第一个数据源保存用户信息,然后在第二个数据源保存产品信息。如果产品名称为"error",则会抛出运行时异常。

    通过在该方法上添加@Transactional(transactionManager = "transactionManager")注解,确保了事务能够正确地跨多个数据源进行管理。当出现异常时,事务会回滚,保证数据的一致性。

  • 30
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伯牙碎琴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值