[翻译] 创建一个只读的Repository接口(Spring Data)

背景

在这个文章中,我们将讨论如何创建一个只读的Spring Data Repository。

有时有必要从数据库中读取数据而无需修改它。在这种情况下,拥有一个只读的Repository接口将是完美的。

它将提供读取数据的功能,不会有修改数据的风险。

添加依赖

<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。

继承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。在主项目范围中不需要此存储库,但此存储对于该测试是必需的。

public interface BookRepository
  extends BookReadOnlyRepository, CrudRepository {}

我们能够测试所有四种只读方法,并且现在可以将ReadOnlyRepository接口重用于其他实体。

总结

我们学习了如何扩展Spring Data的Repository接口,以创建可重用的只读存储库。之后,我们将其绑定到一个简单的Book实体,并编写了一个测试,证明了其功能符合我们的预期。

版权声明:
作者:siwei
链接:https://www.techfm.club/p/27061.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>