0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>В этом уроке мы подробнее обсудим JpaRepository - он устроен интереснее, чем может показаться на первый взгляд. С одной стороны, он предоставляет множество полезных встроенных методов, а с другой - поддерживает автоматическую генерацию кастомных методов для извлечения данных. Далее мы разберем эти возможности.</p>
1
<p>В этом уроке мы подробнее обсудим JpaRepository - он устроен интереснее, чем может показаться на первый взгляд. С одной стороны, он предоставляет множество полезных встроенных методов, а с другой - поддерживает автоматическую генерацию кастомных методов для извлечения данных. Далее мы разберем эти возможности.</p>
2
<h2>CRUD-операции</h2>
2
<h2>CRUD-операции</h2>
3
<p>Сюда входит базовый набор методов для создания, обновления, удаления и выборки данных:</p>
3
<p>Сюда входит базовый набор методов для создания, обновления, удаления и выборки данных:</p>
4
<ul><li><p>Метод S save(S entity) сохраняет данные в базу:</p>
4
<ul><li><p>Метод S save(S entity) сохраняет данные в базу:</p>
5
</li>
5
</li>
6
<li><p>Метод Optional<T> findById(ID id) извлекает сущность по id:</p>
6
<li><p>Метод Optional<T> findById(ID id) извлекает сущность по id:</p>
7
</li>
7
</li>
8
<li><p>Метод List<T> findAll() возвращает список всех сущностей, что полезно для справочников и других небольших таблиц:</p>
8
<li><p>Метод List<T> findAll() возвращает список всех сущностей, что полезно для справочников и других небольших таблиц:</p>
9
</li>
9
</li>
10
<li><p>Метод long count() возвращает количество сущностей, то есть записей в таблице:</p>
10
<li><p>Метод long count() возвращает количество сущностей, то есть записей в таблице:</p>
11
</li>
11
</li>
12
<li><p>Метод void deleteById(ID id) удаляет сущность (запись в базе) по id</p>
12
<li><p>Метод void deleteById(ID id) удаляет сущность (запись в базе) по id</p>
13
</li>
13
</li>
14
<li><p>Метод void delete(T entity) удаляет переданную сущность из базы данных:</p>
14
<li><p>Метод void delete(T entity) удаляет переданную сущность из базы данных:</p>
15
</li>
15
</li>
16
</ul><h2>Derived Query Methods</h2>
16
</ul><h2>Derived Query Methods</h2>
17
<p>Одна из типовых задач - это выборка по определенному полю или набору полей. Spring Data JPA автоматически генерирует методы, выполняющие подобные выборки. Для этого надо добавить определение нужного метода или методов:</p>
17
<p>Одна из типовых задач - это выборка по определенному полю или набору полей. Spring Data JPA автоматически генерирует методы, выполняющие подобные выборки. Для этого надо добавить определение нужного метода или методов:</p>
18
<p>Кроме точного сопоставления параметров, этот механизм умеет генерировать код для множества других условий. Большая часть из них транслируется в SQL достаточно очевидным образом:</p>
18
<p>Кроме точного сопоставления параметров, этот механизм умеет генерировать код для множества других условий. Большая часть из них транслируется в SQL достаточно очевидным образом:</p>
19
<h2>Сортировка</h2>
19
<h2>Сортировка</h2>
20
<p>Сортировка данных выполняется с помощью комбинации методов и вложенных классов Sort:</p>
20
<p>Сортировка данных выполняется с помощью комбинации методов и вложенных классов Sort:</p>
21
<p>Сортировка по возрастанию выполняется с помощью Sort.Order.asc(), по убыванию - с помощью Sort.Order.desc().</p>
21
<p>Сортировка по возрастанию выполняется с помощью Sort.Order.asc(), по убыванию - с помощью Sort.Order.desc().</p>
22
<h2>Пагинация</h2>
22
<h2>Пагинация</h2>
23
<p>Пагинация - это выборка только определенного среза данных с помощью конструкции LIMIT OFFSET. Это основной способ выборки наборов данных, потому что полные наборы обычно слишком большие - извлекать их целиком неудобно:</p>
23
<p>Пагинация - это выборка только определенного среза данных с помощью конструкции LIMIT OFFSET. Это основной способ выборки наборов данных, потому что полные наборы обычно слишком большие - извлекать их целиком неудобно:</p>
24
<p>Обычно текущая страница приходит как параметр запроса. По умолчанию страница равна единице. Это не совпадает с тем, как работает PageRequest - он отображается напрямую на OFFSET, где базовое значение равно 0. Поэтому для правильной работы пагинации нужно выполнить две задачи:</p>
24
<p>Обычно текущая страница приходит как параметр запроса. По умолчанию страница равна единице. Это не совпадает с тем, как работает PageRequest - он отображается напрямую на OFFSET, где базовое значение равно 0. Поэтому для правильной работы пагинации нужно выполнить две задачи:</p>
25
<ul><li>Установить 1 в качестве значения параметра запроса page по умолчанию</li>
25
<ul><li>Установить 1 в качестве значения параметра запроса page по умолчанию</li>
26
<li>При формировании PageRequest вычитать единицы из page</li>
26
<li>При формировании PageRequest вычитать единицы из page</li>
27
</ul><h2>Объединение пагинации и сортировки</h2>
27
</ul><h2>Объединение пагинации и сортировки</h2>
28
<p>Если нужно объединить пагинацию и сортировку, можно задавать сортировку через PageRequest. В итоге код будет выглядеть так:</p>
28
<p>Если нужно объединить пагинацию и сортировку, можно задавать сортировку через PageRequest. В итоге код будет выглядеть так:</p>
29
<h2>Кастомные запросы</h2>
29
<h2>Кастомные запросы</h2>
30
<p>Выше мы перечислили множество разных вариантов. Несмотря на это, в некоторых ситуациях все таки придется написать SQL-код. Чтобы это сделать, нужно добавить определение метода с аннотациями @Param и @Query:</p>
30
<p>Выше мы перечислили множество разных вариантов. Несмотря на это, в некоторых ситуациях все таки придется написать SQL-код. Чтобы это сделать, нужно добавить определение метода с аннотациями @Param и @Query:</p>
31
<p>Советуем писать кастомные запросы только тогда, когда не остается другого выбора.</p>
31
<p>Советуем писать кастомные запросы только тогда, когда не остается другого выбора.</p>