«1. Обзор

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

    CrudRepository PagingAndSortingRepository JpaRepository

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

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

Начнем с JpaRepository, который расширяет PagingAndSortingRepository и, в свою очередь, CrudRepository.

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

    CrudRepository предоставляет функции CRUD. PagingAndSortingRepository предоставляет методы для разбиения на страницы и сортировки записей. JpaRepository предоставляет методы, связанные с JPA, такие как очистка контекста персистентности и пакетное удаление записей.

Итак, из-за этого отношения наследования JpaRepository содержит полный API CrudRepository и 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, Long> {
    Product findByName(String productName);
}

Вот и все. Репозиторий данных Spring автоматически сгенерирует реализацию на основе имени, которое мы ему предоставили.

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

3. CrudRepository

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

public interface CrudRepository<T, ID extends Serializable>
  extends Repository<T, ID> {

    <S extends T> S save(S entity);

    T findOne(ID primaryKey);

    Iterable<T> findAll();

    Long count();

    void delete(T entity);

    boolean exists(ID primaryKey);
}

Обратите внимание на типичную функциональность CRUD: сущности. Здесь мы можем передать несколько объектов, чтобы сохранить их в пакете. findOne(…) — получить один объект на основе переданного значения первичного ключа. — вернуть общее количество сущностей в таблице. delete(…) — удалить сущность на основе переданного объекта.

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

4. PagingAndSortingRepository

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

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

public interface PagingAndSortingRepository<T, ID extends Serializable> 
  extends CrudRepository<T, ID> {

    Iterable<T> findAll(Sort sort);

    Page<T> findAll(Pageable pageable);
}

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

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

  1. Page size
  2. Current page number
  3. Sorting

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

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

5. JpaRepository

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

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

public interface JpaRepository<T, ID extends Serializable> extends
  PagingAndSortingRepository<T, ID> {

    List<T> findAll();

    List<T> findAll(Sort sort);

    List<T> save(Iterable<? extends T> entities);

    void flush();

    T saveAndFlush(T entity);

    void deleteInBatch(Iterable<T> entities);
}

findAll() — get Список всех доступных сущностей в базе данных. Здесь мы можем передать несколько объектов, чтобы сохранить их в пакетном режиме. flush() — сбросить все ожидающие задачи в базу данных «удалить Iterable сущностей. Здесь мы можем передать несколько объектов, чтобы удалить их в пакете

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

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

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

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

  1. we couple our code to the library and to its specific abstractions, such as `Page` or `Pageable`; that’s of course not unique to this library – but we do have to be careful not to expose these internal implementation details
  2. by extending e.g. CrudRepository, we expose a complete set of persistence method at once. This is probably fine in most circumstances as well but we might run into situations where we’d like to gain more fine-grained control over the methods exposed, e.g. to create a ReadOnlyRepository that doesn’t include the save(…) and delete(…) methods of CrudRepository

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

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

«