Динамическое количество параметров в предложении where - PullRequest
0 голосов
/ 29 октября 2018

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

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

в другой раз мне нужно конкретнее { "mark": "Audi", "Модель": "A4" }

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

    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' непосредственно в DB, ​​я получаю правильные результаты.

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

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Предложение будет COALESCE в терминах 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) ;

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

0 голосов
/ 29 октября 2018

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

SELECT * FROM whatever WHERE '123456'

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

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

...