Проверка существования объекта java

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

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

1. введение

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

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

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

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

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 .

Читайте ещё по теме:

Источник

Как проверить, есть ли (Object) в Java?

Но предложение if вызывает ошибку. Он ожидает boolean но Object задан. Java не может преобразовывать типы, не так ли?

Как мне изменить тип или что мне нужно включить в предложение if , чтобы он работал правильно?

Это коллекция (ArrayList) строк.

Object i = it.next(); // I get one element from collection. if (i) < // check if it not the end, if it not the last element of the collection 

Вы пытаетесь проверить, является ли оно нулевым?

Если вы проверяете логическое значение i а ArrayList – это List , тогда вы можете использовать Iterator it , но вам все равно нужно быть осторожным с исключениями из null-указателей.

Edit: Если вы хотите напечатать End когда все ненулевые строки удалены, вы можете удалить блок else и просто распечатать End после цикла for .

Luckly Iterator имеет функцию hasNext() .

Таким образом, вы будете использовать:

Object i = null; if(it.hasNext())< i = it.next(); >else < //done. >//Do stuff with i. 

Неясно, что вы хотите проверить.

Если вы хотите проверить, присутствует ли объект, проверьте значение null:

Если вы хотите проверить какое-либо свойство, то переведите его в определенный тип

if(((MyClass)i).iDontWantLoLive()) 

Если объекты имеют значение boolean, то для boolean:

Java – это строго типизированный язык. Если вы хотите/ожидаете логические значения, тогда сделайте что-то вроде этого…

 List list = new ArrayList(); for (Iterator it = list.iterator(); it.hasNext(); ) < boolean i = it.next(); if (i) < System.out.format("Delete %s%n", i); it.remove(); >else < System.out.println("End"); break; >> 

В противном случае, если вы просто пытаетесь удалить что-то на основании этого значения null, то (‘if (i == null)’, как предложили другие).

Ваш вывод “End” предполагает, что вы хотите сделать это в конце. Вы можете сделать это вместо этого.

List list = c.getArrayList(); for(Object o: list) System.out.println("Delete " + o); list.clear(); System.out.println("End"); 

Примечание: format просто возвращает строку, которую вы отбрасываете.

Это очень медленный способ удалить последний элемент списка. Вместо этого используйте

Да, Java не будет автоматически принуждать типы. Вам придется вручную перевести Object в Boolean .

Если вы просто хотите удалить последний элемент списка, вы можете сделать это:

Источник

How can I check if an element exists in a Set of items?

In an if statement in Java how can I check whether an object exists in a set of items. E.g. In this scenario i need to validate that the fruit will be an apple, orange or banana.

if (fruitname in ["APPLE", "ORANGES", "GRAPES"]) < //Do something >

4 Answers 4

static final List fruits = Arrays.asList("APPLE", "ORANGES", "GRAPES"); if (fruits.contains(fruitname)) 

If your list was much larger, a set would be more efficient.

static final Set fruits = new HashSet( Arrays.asList("APPLE", "ORANGES", "GRAPES", /*many more*/)); 

@wds There isn't really an Arrays.asSet method, and if this is the only use for the collection the extra conversion (to Set) step wouldn't seem worth the effort.

I'm guessing having to hash the key actually takes longer than doing a lookup in a table of a few dozen elements. Still, Set is the right type for the job, even if the particular implementation might not be.

@wds, true, for a small number of entries, it hardly matters which is faster. You can scan a List of 100K entries in about a milli-second which might be fast enough.

for completeness using google-collections/guava:

import com.google.common.collect.Sets; static final Set fruit = Sets.newHashSet("APPLE", "ORANGES", "GRAPES"); if (fruit.contains(fruitname)) 

or using the plane old jdk classes:

static final Set fruit = new HashSet(Arrays.asList("APPLE", "ORANGES", "GRAPES")); 

Is Arrays.binarySearch what you are looking for?

String [] fruits = new String[]; Arrays.sort(fruits); // binarySearch requires that the array is sorted if (Arrays.binarySearch(fruits), fruitname) >= 0) < // found! >
if (ArrayUtils.contains(new String[], fruitname) < // found >

I knew there would be something in Apache Commons 🙂

If you have Set , List , Map of fruits which all have the same parent: Collection , you can try this example.

String fruitName = "Orange"; Collection fruits = . // set of fruits if (fruits.contains(fruitName))

(For Java 8/9/10 ways of creating literal Set please see this SO answer.)

Be careful with case sensitivity (Orange != orange).

Источник

Checking for existence of object by id, name, display name, or web id

My Product class has properties id, name, displayName, wedId .
dataAccessObject.findBy____() returns an object of type Product , if it can be found in the data store, or null if it cannot. I would like to reduce this chunk of code, if possible, because I have many objects that require the doesExist() pattern as above. The client code will only know one of these properties. A possible solution I thought of would be to do this:

public final boolean doesExist(Long id, String name, String displayName, String webId)

and then call it with null for unknown fields while using if statements to determine which field has a value. But is there another way that is more elegant? One of the answers I got over was this, from user StriplingWarrior :

You are recognizing that the "does exist" part of all of these methods is exactly the same, and that makes you want to avoid repeating it, but the "ByXxx" part of these methods is completely different. What you've got is far better than what you're thinking of doing. Please don't change your method signature to require callers to provide null values for all but one argument. That is highly error-prone, as it provides no compile-time errors for a variety of different ways that people might use the method signature incorrectly. One thing you might want to consider doing is separating the "does exist" piece of this into its own mechanism:

public final Optional byId(Long id)

So instead of saying service.doesExistById(123) , you'd say service.byId(123).isPresent() . This represents the same meaning semantically, but it's broken into separate parts, which means you can reuse byId() , byName() , etc., for other purposes where you need the actual object, and not just to know whether it exists.

My ultimate question is, aside from the current solution, is there another way to refactor this code block so I don't have so much repeated similar code?

Источник

Оцените статью