«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:
- Page size
- Current page number
- 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. Заключение
- 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
- 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.
«