CrudRepository, JpaRepository и PagingAndSortingRepository в Spring Data

1. Общ преглед

В тази бърза статия ще се съсредоточим върху различни видове интерфейси на хранилището Spring Data и тяхната функционалност. Ще засегнем:

  • CrudRepository
  • PagingAndSortingRepository
  • JpaRepository

Най-просто казано, всяко хранилище в Spring Data разширява общия интерфейс на хранилището , но освен това, всяко от тях има различна функционалност.

2. Пролетни хранилища за данни

Нека започнем с JpaRepository - който разширява PagingAndSortingRepository и от своя страна CrudRepository .

Всеки от тях определя своята собствена функционалност:

  • CrudRepository предоставя CRUD функции
  • PagingAndSortingRepository предоставя методи за извършване на пагинация и сортиране на записи
  • JpaRepository предоставя методи, свързани с JPA, като измиване на контекста на постоянство и изтриване на записи в партида

И така, поради тази връзка за наследяване, JpaRepository съдържа пълния API на CrudRepository и PagingAndSortingRepository .

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

Нека сега разгледаме един бърз пример, за да разберем по-добре тези API.

Ще започнем с прост продукт :

@Entity public class Product { @Id private long id; private String name; // getters and setters }

И нека приложим проста операция - намерете Продукт въз основа на неговото име:

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

Това е всичко. Хранилището за пролетни данни ще генерира автоматично изпълнението въз основа на името, което сме му предоставили.

Това беше много прост пример, разбира се; можете да навлезете по-дълбоко в Spring Data JPA тук.

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 (...) - ave a Iterable на обекти. Тук можем да предадем множество обекти, за да ги запазим в пакет
  • findOne (...) - вземете единичен обект въз основа на предадена стойност на първичен ключ
  • findAll () - получаване на Iterable от всички налични обекти в базата данни
  • count () - r eturn броят на общите обекти в таблица
  • delete (…) - изтриване на обект въз основа на предадения обект
  • съществува (...) - проверете дали даден обект съществува въз основа на предадената стойност на първичен ключ

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

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 () - получаване на списък на всички налични обекти в базата данни
  • findAll (...) - вземете списък на всички налични обекти и ги сортирайте, като използвате предоставеното условие
  • save (...) - ave a Iterable на обекти. Тук можем да предадем множество обекти, за да ги запазим в пакет
  • flush () - f буйни всички чакащи задачи в базата данни
  • saveAndFlush (...) - запазете обекта и незабавно измийте промените
  • deleteInBatch (...) - изтриване на Iterable обекти. Тук можем да предадем множество обекти, за да ги изтрием в пакет

Ясно е, че горният интерфейс разширява PagingAndSortingRepository, което означава, че има всички методи, налични и в CrudRepository .

6. Недостатъци на пролетните хранилища за данни

Beyond all the very useful advantages of these repositories, there are some basic downsides of directly depending on these as well:

  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

7. Conclusion

Тази статия обхваща някои кратки, но важни разлики и характеристики на интерфейсите на хранилището Spring Data JPA.

За повече информация разгледайте поредицата за Пролетна упоритост.