使用Spring數據創建只讀Repository

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實體,並編寫了一個測試,證明了其功能符合我們的預期。