CrudRepository, JpaRepository и PagingAndSortingRepository в Spring Data

CrudRepository, JpaRepository и PagingAndSortingRepository в данных Spring

1. обзор

В этой быстрой статье мы сосредоточимся на различных типах интерфейсов репозитория Spring Data и их функциональности. Мы коснемся:

  • CrudRepository

  • PagingAndSortingRepository

  • JpaRepository

Проще говоря, каждый репозиторий вSpring Data расширяет общий интерфейсRepository, но помимо этого, каждый из них имеет разные функции.

2. Репозитории данных Spring

Let’s start with the JpaRepository - расширяетPagingAndSortingRepository и, в свою очередь,CrudRepository.

Каждый из них определяет свою собственную функциональность:

  • CrudRepository предоставляет функции CRUD

  • PagingAndSortingRepository предоставляет методы для разбивки на страницы и сортировки записей

  • JpaRepository предоставляет методы, связанные с JPA, такие как очистка контекста сохранения и удаление записей в пакете.

Итак, из-за этого отношения наследованияJpaRepository contains the full API of CrudRepository and PagingAndSortingRepository.

Когда нам не нужна полная функциональность, предоставляемаяJpaRepository иPagingAndSortingRepository, мы можем просто использоватьCrudRepository.

Давайте теперь рассмотрим быстрый пример, чтобы лучше понять эти API.

Начнем с простой сущностиProduct:

@Entity
public class Product {

    @Id
    private long id;
    private String name;

    // getters and setters
}

И давайте реализуем простую операцию - найдемProduct по его имени:

@Repository
public interface ProductRepository extends JpaRepository {
    Product findByName(String productName);
}

Вот и все. Spring Data Repository автоматически сгенерирует реализацию на основе предоставленного нами имени.

Конечно, это был очень простой пример; вы можете глубже изучить Spring Data JPAhere.

3. CrudRepositoryс

Теперь посмотрим на код интерфейсаCrudRepository:

public interface CrudRepository
  extends Repository {

     S save(S entity);

    T findOne(ID primaryKey);

    Iterable findAll();

    Long count();

    void delete(T entity);

    boolean exists(ID primaryKey);
}

Обратите внимание на типичные функции CRUD:

  • save(…) – sсохранитьIterable сущностей. Здесь мы можем передать несколько объектов, чтобы сохранить их в пакете

  • findOne(…) - получить единую сущность на основе переданного значения первичного ключа

  • findAll() - получитьIterable всех доступных сущностей в базе данных

  • count() – rустановить количество всех сущностей в таблице

  • delete(…) - удалить сущность на основе переданного объекта

  • exist (…) - проверить, существует ли сущность на основе переданного значения первичного ключа

Этот интерфейс выглядит довольно общим и простым, но на самом деле он предоставляет все основные абстракции запросов, необходимые в приложении.

4. PagingAndSortingRepositoryс

Теперь давайте посмотрим на другой интерфейс репозитория, расширяющийCrudRepository:

public interface PagingAndSortingRepository
  extends CrudRepository {

    Iterable findAll(Sort sort);

    Page findAll(Pageable pageable);
}

Этот интерфейс предоставляет методfindAll(Pageable pageable), который является ключом к реализацииPagination.

При использованииPageable мы создаем объектPageable с определенными свойствами, и мы должны указать как минимум:

  1. Размер страницы

  2. Номер текущей страницы

  3. Сортировка

Итак, предположим, что мы хотим показать первую страницу набора результатов, отсортированную по возрастаниюlastName,, имея не более пяти записей в каждой. Вот как мы можем добиться этого, используя определениеPageRequest иSort:

Sort sort = new Sort(new Sort.Order(Direction.ASC, "lastName"));
Pageable pageable = new PageRequest(0, 5, sort);

Передача страничного объекта в запрос данных Spring вернет рассматриваемые результаты (первый параметрPageRequest отсчитывается от нуля).

5. JpaRepositoryс

Наконец, посмотрим на интерфейсJpaRepository:

public interface JpaRepository extends
  PagingAndSortingRepository {

    List findAll();

    List findAll(Sort sort);

    List save(Iterable entities);

    void flush();

    T saveAndFlush(T entity);

    void deleteInBatch(Iterable entities);
}

Опять же, давайте кратко рассмотрим каждый из этих методов:

  • findAll() - получитьList всех доступных сущностей в базе данных

  • findAll(…) - получитьList всех доступных сущностей и отсортировать их, используя предоставленное условие

  • save(…) – sсохранитьIterable сущностей. Здесь мы можем передать несколько объектов, чтобы сохранить их в пакете

  • flush() – fубрать все отложенные задачи в базу данных

  • saveAndFlush(…) - сохранить сущность и немедленно сбросить изменения

  • deleteInBatch (…) - удалитьIterableсущностей. Здесь мы можем передать несколько объектов, чтобы удалить их в пакете

Ясно, что указанный выше интерфейс расширяетPagingAndSortingRepository, что означает, что он также имеет все методы, присутствующие вCrudRepository.

6. Недостатки репозиториев данных Spring

Помимо всех очень полезных преимуществ этих репозиториев, есть несколько основных недостатков, которые напрямую зависят от них:

  1. мы связываем наш код с библиотекой и ее конкретными абстракциями, такими какPage илиPageable; это, конечно, не является уникальным для этой библиотеки, но мы должны быть осторожны, чтобы не раскрывать эти внутренние детали реализации

  2. расширяя, например, CrudRepository, мы сразу выставляем полный набор методов персистентности. Это, вероятно, нормально и в большинстве случаев, но мы можем столкнуться с ситуациями, когда мы хотели бы получить более точный контроль над открытыми методами, например чтобы создатьReadOnlyRepository, который не включает методыsave(…) иdelete(…) изCrudRepository

7. Заключение

В этой статье были рассмотрены некоторые краткие, но важные отличия и особенности интерфейсов репозитория Spring Data JPA.

Для получения дополнительной информации посмотрите серию поSpring Persistence.