只读副本和Spring Data第4部分:配置只读存储库

以前,我们在同一应用程序中设置了两个EntityManager。 一种用于读取,另一种用于写入。 现在是时候创建我们的读取存储库了。

只读存储库将使用辅助只读EntityManager。

为了使其成为只读存储库,至关重要的是不要执行任何保存和持久操作。

 package com.gkatzioura.springdatareadreplica.repository;  import java.util.List;  import org.springframework.data.repository.Repository;  import com.gkatzioura.springdatareadreplica.config.ReadOnlyRepository;  import com.gkatzioura.springdatareadreplica.entity.Employee;  /** 
  * This is a read only repository 
  */  public interface ReadEmployeeRepository extends Repository { 
     List findAll();  } 

我们的下一个任务是使用读取数据库实体管理器创建此存储库。
这意味着除只读存储库外,所有存储库均应使用默认实体管理器创建。

我将首先创建一个注释。 此注释将声明我的存储库为只读。 另外,我将使用此批注进行扫描操作,以便使用适当的EntityManager。

 package com.gkatzioura.springdatareadreplica.config;  import java.lang.annotation.Documented;  import java.lang.annotation.ElementType;  import java.lang.annotation.Retention;  import java.lang.annotation.RetentionPolicy;  import java.lang.annotation.Target;  @Retention (RetentionPolicy.RUNTIME)  @Target ({ElementType.TYPE})  @Documented  public @interface ReadOnlyRepository {  } 

现在,我知道Spring Boot消除了对注释的需求,并以自动化的方式创建了存储库,但是我们的案例很特殊。

通过进行一些调整,我们的只读存储库将如下所示

 package com.gkatzioura.springdatareadreplica.repository;  import java.util.List;  import org.springframework.data.repository.Repository;  import com.gkatzioura.springdatareadreplica.config.ReadOnlyRepository;  import com.gkatzioura.springdatareadreplica.entity.Employee;  /** 
  * This is a read only repository 
  */  @ReadOnlyRepository  public interface ReadEmployeeRepository extends Repository { 
     List findAll();  } 

现在是时候使用我们的存储库扫描了。 除使用@ReadOnlyRepository批注进行注释的存储库外,所有存储库均将注入主EntityManager。

 package com.gkatzioura.springdatareadreplica.config;  import javax.sql.DataSource;  import org.springframework.beans.factory.annotation.Qualifier;  import org.springframework.beans.factory.annotation.Value;  import org.springframework.boot.jdbc.DataSourceBuilder;  import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;  import org.springframework.context.annotation.Bean;  import org.springframework.context.annotation.ComponentScan;  import org.springframework.context.annotation.Configuration;  import org.springframework.context.annotation.Primary;  import org.springframework.data.jpa.repository.config.EnableJpaRepositories;  import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;  @Configuration  @EnableJpaRepositories ( 
         basePackages = "com.gkatzioura" , 
         excludeFilters = @ComponentScan .Filter(ReadOnlyRepository. class ), 
         entityManagerFactoryRef = "entityManagerFactory"  )  public class PrimaryEntityManagerConfiguration { 
     @Value ( "${spring.datasource.username}" ) 
     private String username; 
     @Value ( "${spring.datasource.password}" ) 
     private String password; 
     @Value ( "${spring.datasource.url}" ) 
     private String url; 
     @Bean 
     @Primary 
     public DataSource dataSource() throws Exception { 
         return DataSourceBuilder.create() 
                                 .url(url) 
                                 .username(username) 
                                 .password(password) 
                                 .driverClassName( "org.postgresql.Driver" ) 
                                 .build(); 
     } 
     @Bean 
     @Primary 
     public LocalContainerEntityManagerFactoryBean entityManagerFactory( 
             EntityManagerFactoryBuilder builder, 
             @Qualifier ( "dataSource" ) DataSource dataSource) { 
         return builder.dataSource(dataSource) 
                       .packages( "com.gkatzioura.springdatareadreplica" ) 
                       .persistenceUnit( "main" ) 
                       .build(); 
     }  } 

同样,我们将为只读存储库添加配置。

 package com.gkatzioura.springdatareadreplica.config;  import javax.sql.DataSource;  import org.springframework.beans.factory.annotation.Qualifier;  import org.springframework.beans.factory.annotation.Value;  import org.springframework.boot.jdbc.DataSourceBuilder;  import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;  import org.springframework.context.annotation.Bean;  import org.springframework.context.annotation.ComponentScan;  import org.springframework.context.annotation.Configuration;  import org.springframework.data.jpa.repository.config.EnableJpaRepositories;  import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;  @Configuration  @EnableJpaRepositories ( 
         basePackages = "com.gkatzioura" , 
         includeFilters= @ComponentScan .Filter(ReadOnlyRepository. class ), 
         entityManagerFactoryRef = "readEntityManagerFactory"  )  public class ReadOnlyEntityManagerConfiguration { 
     @Value ( "${spring.datasource.username}" ) 
     private String username; 
     @Value ( "${spring.datasource.password}" ) 
     private String password; 
     @Value ( "${spring.datasource.readUrl}" ) 
     private String readUrl; 
     @Bean 
     public DataSource readDataSource() throws Exception { 
         return DataSourceBuilder.create() 
                                 .url(readUrl) 
                                 .username(username) 
                                 .password(password) 
                                 .driverClassName( "org.postgresql.Driver" ) 
                                 .build(); 
     } 
     @Bean 
     public LocalContainerEntityManagerFactoryBean readEntityManagerFactory( 
             EntityManagerFactoryBuilder builder, 
             @Qualifier ( "readDataSource" ) DataSource dataSource) { 
         return builder.dataSource(dataSource) 
                       .packages( "com.gkatzioura.springdatareadreplica" ) 
                       .persistenceUnit( "read" ) 
                       .build(); 
     }  } 

辅助实体管理器将仅注入仅具有@ReadOnlyRepository批注的存储库。

为了说明这一点,让我们对控制器进行一些更改。

 package com.gkatzioura.springdatareadreplica.controller;  import java.util.List;  import org.springframework.http.HttpStatus;  import org.springframework.web.bind.annotation.GetMapping;  import org.springframework.web.bind.annotation.PostMapping;  import org.springframework.web.bind.annotation.RequestBody;  import org.springframework.web.bind.annotation.ResponseStatus;  import org.springframework.web.bind.annotation.RestController;  import com.gkatzioura.springdatareadreplica.entity.Employee;  import com.gkatzioura.springdatareadreplica.repository.EmployeeRepository;  import com.gkatzioura.springdatareadreplica.repository.ReadEmployeeRepository;  @RestController  public class EmployeeContoller { 
     private final EmployeeRepository employeeRepository; 
     private final ReadEmployeeRepository readEmployeeRepository; 
     public EmployeeContoller(EmployeeRepository employeeRepository, 
                              ReadEmployeeRepository readEmployeeRepository) { 
         this .employeeRepository = employeeRepository; 
         this .readEmployeeRepository = readEmployeeRepository; 
     } 
     @GetMapping ( "/employee" ) 
     public List getEmployees() { 
         return employeeRepository.findAll(); 
     } 
     @GetMapping ( "/employee/read" ) 
     public List getEmployeesRead() { 
         return readEmployeeRepository.findAll(); 
     } 
     @PostMapping ( "/employee" ) 
     @ResponseStatus (HttpStatus.CREATED) @ResponseStatus (HttpStatus.CREATED) 
     public void addEmployee( @RequestBody Employee employee) { 
         employeeRepository.save(employee); 
     }  } 

当您将员工添加到系统时,只读存储库将继续获取旧员工,而主存储库将获取所有员工,包括最近保留的员工。

翻译自: https://www.javacodegeeks.com/2019/10/read-replicas-and-spring-data-configuring-the-read-repository.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值