1.概述
在这个简短的教程中,我们将讨论如何创建一个只读的Spring Data **Repository.**
有时有必要从数据库中读取数据而无需修改它。在这种情况下,拥有只读的Repository接口将是完美的。
它将提供读取数据的功能,而无需任何人更改它的风险。
2.扩展Repository
让我们从一个包含spring-boot-starter-data-jpa依赖项的Spring Boot项目开始:
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-jpa</artifactId>
 <version>2.4.3</version>
 </dependency>Spring Data受欢迎的CrudRepository ,该接口提供了大多数应用程序所需的所有基本CRUD操作(创建,读取,更新,删除)的方法。但是,它包含几种修改数据的方法,我们需要一个只能读取数据的存储库。
CrudRepository实际上扩展了另一个称为Repository接口。我们还可以扩展此接口以满足我们的需求。
让我们创建一个扩展Repository的新接口:
@NoRepositoryBean
 public interface ReadOnlyRepository<T, ID> extends Repository<T, ID> {
 Optional<T> findById(ID id);
 List<T> findAll();
 }在这里,我们仅定义了两个只读方法。此存储库访问的实体将不受任何修改的影响。
还必须注意,我们必须使用@NoRepositoryBean批注来告诉Spring我们希望该存储库保持通用性,这一点也很重要。这使我们可以根据需要将只读存储库重用于许多不同的实体。
接下来,我们将看到如何将实体绑定到我们的新ReadOnlyRepository 。
3.扩展ReadOnlyRepository
假设我们有一个要访问Book
@Entity
 public class Book {
 @Id
 @GeneratedValue
 private Long id;
 private String author;
 private String title;
 //getters and setters
 }现在我们有了一个可持久的实体,我们可以创建一个继承自ReadOnlyRepository的存储库接口:
public interface BookReadOnlyRepository extends ReadOnlyRepository<Book, Long> {
 List<Book> findByAuthor(String author);
 List<Book> findByTitle(String title);
 }除了它继承的两个方法外,我们还添加了两个特定于Book的只读方法: findByAuthor()和findByTitle() 。总共,此存储库可以访问四种只读方法。
最后,让我们编写一个测试来确保BookReadOnlyRepository的功能:
@Test
 public void givenBooks_whenUsingReadOnlyRepository_thenGetThem() {
 Book aChristmasCarolCharlesDickens = new Book();
 aChristmasCarolCharlesDickens.setTitle("A Christmas Carol");
 aChristmasCarolCharlesDickens.setAuthor("Charles Dickens");
 bookRepository.save(aChristmasCarolCharlesDickens);
 Book greatExpectationsCharlesDickens = new Book();
 greatExpectationsCharlesDickens.setTitle("Great Expectations");
 greatExpectationsCharlesDickens.setAuthor("Charles Dickens");
 bookRepository.save(greatExpectationsCharlesDickens);
 Book greatExpectationsKathyAcker = new Book();
 greatExpectationsKathyAcker.setTitle("Great Expectations");
 greatExpectationsKathyAcker.setAuthor("Kathy Acker");
 bookRepository.save(greatExpectationsKathyAcker);
 List<Book> charlesDickensBooks = bookReadOnlyRepository.findByAuthor("Charles Dickens");
 Assertions.assertEquals(2, charlesDickensBooks.size());
 List<Book> greatExpectationsBooks = bookReadOnlyRepository.findByTitle("Great Expectations");
 Assertions.assertEquals(2, greatExpectationsBooks.size());
 List<Book> allBooks = bookReadOnlyRepository.findAll();
 Assertions.assertEquals(3, allBooks.size());
 Long bookId = allBooks.get(0).getId();
 Book book = bookReadOnlyRepository.findById(bookId).orElseThrow(NoSuchElementException::new);
 Assertions.assertNotNull(book);
 }为了在读回书之前将书保存到数据库中,我们创建了一个BookRepository CrudRepository在测试范围内扩展了CrudRepository。在主项目范围中不需要此存储库,但此存储对于该测试是必需的。
public interface BookRepository
 extends BookReadOnlyRepository, CrudRepository<Book, Long> {}我们能够测试所有四种只读方法,并且现在可以将ReadOnlyRepository接口重用于其他实体。
4 结论
我们学习了如何扩展Spring Data的Repository接口,以创建可重用的只读存储库。之后,我们将其绑定到一个简单的Book实体,并编写了一个测试,证明了其功能符合我们的预期。

 
							 
										
										 
										
										 
										
										
										 
										
										 
										
										 
										
										
0 评论