В чем разница между интерфейсами CrudRepository и JpaRepository в Spring Data JPA?

В чем разница между интерфейсами CrudRepository и JpaRepository в Spring Data JPA?

Когда я вижу примеры в Интернете, я вижу, что они используются взаимозаменяемо. В чем разница между ними? Почему вы хотите использовать один поверх другого?

Ответ 1

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

Их основными функциями являются:

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

Из-за упомянутого выше наследования JpaRepository будет иметь все функции CrudRepository и PagingAndSortingRepository. Поэтому, если вам не нужен репозиторий, чтобы иметь функции, предоставляемые JpaRepository и PagingAndSortingRepository, используйте CrudRepository.

Ответ 2

Ответ Кена в основном правильный, но я хотел бы ответить на вопрос "почему вы хотите использовать один над другим?" часть вашего вопроса.

основы

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

Общие интерфейсы

Базовая библиотека Spring Data поставляется с двумя базовыми интерфейсами, которые предоставляют выделенный набор функций:

  • CrudRepository - методы CRUD
  • PagingAndSortingRepository - методы разбивки на страницы и сортировки (расширяет CrudRepository)

Специфичные для магазина интерфейсы

Отдельные модули хранилища (например, для JPA или MongoDB) предоставляют специфичные для магазина расширения этих базовых интерфейсов, чтобы обеспечить доступ к специфическим для хранилища функциям, таким как очистка или выделенная группировка, которые принимают во внимание некоторые особенности хранилища. Примером этого является deleteInBatch(…) JpaRepository который отличается от delete(…) как он использует запрос для удаления заданных объектов, который является более производительным, но имеет побочный эффект - не вызывает JPA-определенные каскады (как спецификация определяет это).

Как правило, мы рекомендуем не использовать эти базовые интерфейсы, поскольку они предоставляют клиентам базовую технологию персистентности и, таким образом, усиливают связь между ними и хранилищем. Кроме того, вы немного отошли от первоначального определения хранилища, которое по сути является "набором сущностей". Так что, если можете, оставайтесь с PagingAndSortingRepository.

Пользовательские интерфейсы репозитория

Недостаток прямой зависимости от одного из предоставленных базовых интерфейсов - двоякий. Оба они могут рассматриваться как теоретические, но я думаю, что важно знать о них:

  1. В зависимости от интерфейса хранилища Spring Data интерфейс хранилища соединяется с библиотекой. Я не думаю, что это особая проблема, так как вы все равно будете использовать абстракции, такие как Page или Pageable в любом случае. Spring Data ничем не отличается от любой другой библиотеки общего назначения, такой как commons-lang или Guava. Пока это обеспечивает разумную выгоду, это просто прекрасно.
  2. Расширяя, например, CrudRepository, вы сразу выставляете полный набор методов персистентности. Это, вероятно, хорошо в большинстве случаев, но вы можете столкнуться с ситуациями, когда вы хотите получить более детальный контроль над методами, например, создать ReadOnlyRepository, который не включает save(…) и delete(…) Методы CrudRepository.

Решение обоих этих недостатков заключается в создании собственного интерфейса базового хранилища или даже набора из них. Во многих приложениях я видел что-то вроде этого:

interface ApplicationRepository<T> extends PagingAndSortingRepository<T, Long> { }

interface ReadOnlyRepository<T> extends Repository<T, Long> {

  // Al finder methods go here
}

Первый интерфейс репозитория - это некоторый базовый интерфейс общего назначения, который фактически только фиксирует точку 1, но также связывает тип идентификатора с типом Long для согласованности. Второй интерфейс обычно имеет все методы find…(…) скопированные из CrudRepository и PagingAndSortingRepository но не предоставляет манипулирующие. Подробнее об этом подходе читайте в справочной документации.

Резюме - tl; dr

Абстракция хранилища позволяет вам выбрать базовое хранилище, полностью ориентированное на ваши архитектурные и функциональные потребности. Используйте предоставляемые из коробки, если они подходят, создайте свои собственные базовые интерфейсы репозитория, если это необходимо. Держитесь подальше от хранилища определенных интерфейсов хранилища, если это неизбежно.

Ответ 3

enter image description here

Резюме:

  • PagingAndSortingRepository расширяет CrudRepository

  • JpaRepository расширяет PagingAndSortingRepository

Интерфейс CrudRepository предоставляет методы для операций CRUD, поэтому он позволяет создавать, считывать, обновлять и удалять записи без необходимости определения собственных методов.

PagingAndSortingRepository предоставляет дополнительные методы для извлечения сущностей, используя разбиение на страницы и сортировку.

Наконец, JpaRepository добавляет еще несколько функций, специфичных для JPA.

Ответ 4

Я изучаю Spring Data JPA. Это может помочь вам: enter image description here