Рубрики
Без рубрики

Запрос Exists в данных Spring

Узнайте, как проверить, существует ли объект в базе данных, используя Spring Data и JPA.

Автор оригинала: baeldung.

1. введение

Во многих приложениях, ориентированных на данные, могут возникнуть ситуации, когда нам нужно проверить, существует ли уже определенный объект.

В этом уроке мы обсудим несколько способов достижения именно этого с помощью Spring Data и JPA.

2. Образец объекта

Чтобы подготовить почву для наших примеров, давайте создадим сущность Car с двумя свойствами: model и power :

@Entity
public class Car {

    @Id
    @GeneratedValue
    private int id;

    private Integer power;
    private String model;
    
    // getters, setters, ...
}

3. Поиск по идентификатору

Интерфейс JpaRepository предоставляет метод exists By Id , который проверяет, существует ли сущность с заданным id в базе данных:

int searchId = 2; // ID of the Car
boolean exists = repository.existsById(searchId)

Предположим, что searchId – это id автомобиля , который мы создали во время настройки теста. Ради повторяемости теста мы никогда не должны использовать жестко закодированное число (например, “2”), потому что свойство id автомобиля , скорее всего, генерируется автоматически и может изменяться с течением времени. Запрос существует по идентификатору является самым простым, но наименее гибким способом проверки существования объекта .

4. Использование производного метода запроса

Мы также можем использовать функцию метода производных запросов Spring для формулировки нашего запроса. В нашем примере мы хотим проверить, существует ли Car с заданным именем модели, поэтому мы разрабатываем следующий метод запроса:

boolean existsCarByModel(String model);

Важно отметить, что имя метода не является произвольным — он должен следовать определенным правилам . Затем Spring сгенерирует прокси-сервер для репозитория, чтобы он мог получить SQL-запрос из имени метода. Современные IDE, такие как IntelliJ IDEA, обеспечат завершение синтаксиса для этого.

Когда запросы становятся более сложными – например, за счет включения порядка, ограничения результатов и нескольких критериев запроса – эти имена методов могут становиться довольно длинными, вплоть до неразборчивости . Кроме того, производные методы запроса могут показаться волшебными из-за их неявной и “условной” природы.

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

5. Поиск по примеру

Example – это очень мощный способ проверки существования, поскольку он использует Example Matchers для динамического построения запроса. Поэтому всякий раз, когда нам требуется динамичность, это хороший способ сделать это. Подробное объяснение совпадений Spring Example и способов их использования можно найти в нашей статье Spring Data Query .

5.1. Сопоставитель

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

ExampleMatcher modelMatcher = ExampleMatcher.matching()
  .withIgnorePaths("id") 
  .withMatcher("model", ignoreCase());

Обратите внимание, что мы должны явно игнорировать путь id , поскольку id является первичным ключом, и по умолчанию они выбираются автоматически.

5.2. Зонд

Затем нам нужно определить так называемый “зонд”, который является экземпляром класса, который мы хотим найти. В нем заданы все свойства, относящиеся к поиску. Затем мы подключаем его к нашему nameMatcher и выполняем запрос:

Car probe = new Car();
probe.setModel("bmw");
Example example = Example.of(probe, modelMatcher);
boolean exists = repository.exists(example);

С большой гибкостью приходит большая сложность, и каким бы мощным ни был Example Matcher API, его использование приведет к появлению довольно большого количества строк дополнительного кода. Мы предлагаем использовать это в динамических запросах или, если никакой другой метод не подходит для этой цели .

6. Написание пользовательского запроса JPQL с семантикой Exists

Последний метод, который мы рассмотрим, использует JPQL (Java Persistence Query Language) для реализации пользовательского запроса с семантикой exists :

@Query("select case when count(c)> 0 then true else false end from Car c where lower(c.model) like lower(:model)")
boolean existsCarLikeCustomQuery(@Param("model") String model);

Идея состоит в том, чтобы выполнить запрос без учета регистра count на основе свойства model , оценить возвращаемое значение и сопоставить результат с Java boolean . Опять же, большинство IDE имеют довольно хорошую поддержку операторов JPQL.

Пользовательские запросы JPQL можно рассматривать как альтернативу производным методам и часто являются хорошим выбором, когда нам удобно работать с SQL-подобными операторами и мы не возражаем против дополнительных @Query аннотаций.

7. Заключение

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

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

Полный пример исходного кода можно найти на GitHub .