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

706

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

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

В чем разница между ними?

Почему вы хотите использовать один поверх другого?

kseeker
источник
Также прочитайте раздел этой статьи Введение в репозитории данных Spring
Lucky

Ответы:

956

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

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

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

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

Кен Чан
источник
143
и возвращает List <> вместо Iterable <> в findAll () :-)
Hinotori
397

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

основы

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

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

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

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

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

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

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

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

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

  1. В зависимости от интерфейса хранилища данных Spring интерфейс хранилища связывается с библиотекой. Я не думаю, что это особая проблема, так как вы, вероятно, в любом случае будете использовать абстракции, такие как 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

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

Оливер Дротбом
источник
84

введите описание изображения здесь

Резюме:

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

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

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

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

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

Джоби Уилсон Мэтьюз
источник
А как насчет "расширяет репозиторий <>"? Какие у него будут методы? Так же, как CrudRepository?
s-kaczmarek
15

Я изучаю Spring Data JPA. Это может помочь вам: введите описание изображения здесь

Evan
источник
3

Все ответы содержат достаточные детали к вопросу. Однако позвольте мне добавить кое-что еще.

Почему мы используем эти интерфейсы:

  • Они позволяют Spring находить ваши интерфейсы репозитория и создавать для них прокси-объекты.
  • Он предоставляет вам методы, которые позволяют вам выполнять некоторые общие операции (вы также можете определить свой собственный метод). Мне нравится эта особенность, потому что создание метода (и определение запроса и подготовленных операторов, а затем выполнение запроса с объектом соединения) для выполнения простой операции - отстой!

Какой интерфейс делает что:

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

Когда использовать какой интерфейс:

Согласно http://jtuts.com/2014/08/26/difference-between-crudrepository-and-jparepository-in-spring-data-jpa/

Как правило, лучше всего использовать CrudRepository или PagingAndSortingRepository в зависимости от того, нужна ли вам сортировка и разбиение по страницам или нет.

По возможности следует избегать JpaRepository , поскольку он связывает ваши репозитории с технологией постоянства JPA, и в большинстве случаев вы, вероятно, даже не будете использовать дополнительные методы, предоставляемые им.

Рахул Вала
источник