Динамическое количество параметров в предложении where

Вначале я должен сказать, что способ, которым я пытаюсь это сделать, может быть глупым, но это только один, который я понял.

У меня есть таблица со свойствами автомобиля, один раз мне нужно получить дату по одному параметру { "mark": "Audi" }

в другой раз мне нужно более конкретное { "mark": "Audi", «модель»: «А4» }

Итак, я пишу метод

    public List<Object> findVehicleProperty(String propertyType, Vehicle vehicle) {
    String queryParam = "";

    if (vehicle.getMark() != null) queryParam += "mark='"+vehicle.getMark()+"'&";
    if (vehicle.getModel() != null) queryParam += "model='"+vehicle.getModel()+"'&";
    if (vehicle.getEnginePower() != null) queryParam += "engine_power = "+vehicle.getEnginePower()+"&";
    if (vehicle.getSeatCount() != null) queryParam += "seat_count = "+vehicle.getSeatCount()+"&";
    if (vehicle.getDoorsCount() != null) queryParam += "doors_count = "+vehicle.getDoorsCount()+"&";
    if (vehicle.getGearboxCount() != null) queryParam += "gearbox_count = "+vehicle.getGearboxCount()+"&";
    if (vehicle.getType() != null) queryParam += "type = "+vehicle.getType()+"&";


    //remove last "&" mark
    if (queryParam.length() > 0) {
        queryParam = queryParam.substring(0, queryParam.length() - 1);
    }


    return vehicleRepository.getParameters(queryParam);
}

которые возвращают предложение WHERE из sql "mark = Audi & model = A4, затем я попытался передать эту часть sql в качестве параметра в репозиторий.

@Query(value = "select * from Vehicle where ?1", nativeQuery = true)
List<Object> getParameters(String query);

Я утешаюсь, я вижу, что он хорошо вставляет

2018-10-29 21:35:57.488 DEBUG 6240 --- [nio-8080-exec-1] org.hibernate.SQL                        : select * from Vehicle where ?

2018-10-29 21:35:57.494 TRACE 6240 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [VARCHAR] - [mark='Audi'&model='A4']

но этот запрос всегда возвращает пустую коллекцию, если я использую select * from Vehicle, где mark = 'Audi' & model = 'A4' непосредственно в БД, я получаю правильные результаты.

Ты хоть представляешь почему?

Вы имеете дело с SQL, а не с параметрами запроса url. Это должен быть mark=Audi AND model=A4.

tsolakp 29.10.2018 21:44

Самое смешное, что он не получает синтаксической ошибки SQL;)

Antoniossss 29.10.2018 21:46

Скорее всего, он ищет автомобильную марку Audi&model=A4.

tsolakp 29.10.2018 21:47

Это не тот случай. Только отметкой = 'Audi' я все еще ничего не получаю

plucins 29.10.2018 21:48

@tsilakp Неее в этом тоже нет никакого смысла.

Antoniossss 29.10.2018 21:48

Вы уверены, что можете сделать что-то подобное в SQL mark='Audi'&model='A4'. Что это за БД? Это просто недопустимый SQL, поэтому он не должен работать ни в коем случае.

Antoniossss 29.10.2018 21:50

@plucins Затем покажите, как данные хранятся в БД. Является ли значение столбца в JSON?

tsolakp 29.10.2018 21:50

@Antoniossss Я не вижу одинарных кавычек вокруг значений в его примере или коде.

tsolakp 29.10.2018 21:54

Его MySql - imgur.com/BuV7BnC

plucins 29.10.2018 21:55

@tsolakp зачем тебе? Это идея подготовленных заявлений, чтобы делать такие вещи за вас.

Antoniossss 29.10.2018 21:55

С каких это пор & является действительной заменой AND ??

Antoniossss 29.10.2018 21:56

@Antoniossss. Будет ли JDBC помещать одинарные кавычки внутри строкового значения или только вокруг него?

tsolakp 29.10.2018 21:57

ИМХО он должен генерировать исключение, но похоже, что он ускользает от значения с помощью ''. И определенно вокруг него.

Antoniossss 29.10.2018 21:59
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
13
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы не можете использовать подготовленные операторы для «вставки» всего предложения where, так как оно ускользнет от вашей «собственной строки», поэтому вы получите

SELECT * FROM whatever WHERE '123456'

или что-то подобное.

Для динамических критериев (это ваш случай) используйте CriteriaAPI, поэтому CriteriaBuilder будет здесь вашим другом.

Большое спасибо. Я сделал это, используя Ваше предложение использовать Criteria API и его работу, как я ожидал

plucins 30.10.2018 18:52

Предложение было бы КОЛЕСЦЕ в терминах SQL.

НЕ УВЕРЕН, РАБОТАЕТ ЛИ ЭТО весной

И в вашем случае это может работать так:

SELECT * 
FROM Vehicle 
WHERE COALESCE(mark = :mark, true) and 
      COALESCE(model = :model, true)  and   
      COALESCE(engine_power = :engine_power, true) and 
      COALESCE(seat_count = :seat_count, true) and 
      COALESCE(doors_count = :doors_count, true) and 
      COALESCE(gearbox_count = :gearbox_count, true) and 
      COALESCE(type = :type, true) ;

Это предполагает, что вы поместите все возможные параметры как " and COALESCE(attribute = :attribute , true)" or " and COALESCE(attribute= ?1 , true)"

Почему не w3schools.com?
Ilyes 12.06.2021 13:15

Другие вопросы по теме