Передавать переменные из кода Java в SQL или PL / SQL - PullRequest
1 голос
/ 31 августа 2011

Мне нужно связать максимум 8 переменных. Каждый из них может быть null . Есть ли рекомендуемый способ для достижения этой цели? Я знаю, что могу просто проверить null , но это кажется утомительным.

Дополнительные детали :
Я собираюсь вызвать этот sql из кода Java. Он может быть написан с использованием JPA 2.0 Criteria API , но, скорее всего, это будет собственный запрос. База данных Oracle 10g , поэтому я думаю, что я мог бы также использовать PL / SQL .

Edit1:
Возможно, название немного вводит в заблуждение, поэтому я попытаюсь уточнить. Результирующий SQL будет выглядеть примерно так:
...<br> WHERE var1 = :var1<br> AND var2 = :var2<br> ...<br> AND var = :var8
Теперь мне нужно связать параметры из Java-кода следующим образом:
nativeQuery.setParameter("var1", var1)<br> ...<br> nativeQuery.setParameter("var8", var8)
Некоторые параметры могут быть нулевыми, поэтому нет необходимости связывать их. Но я не вижу, как я могу опустить их в SQL.

Edit2: Я ожидаю увидеть процедуру SQL или PL / SQL в ваших ответах (если это возможно без проверки null ). На самом деле, все эти переменные имеют одинаковый тип. Я думаю, что невозможно найти решение с использованием ANSI SQL, но, может быть, есть некоторые процедуры PL / SQL, которые позволяют работать с varargs?

Ответы [ 2 ]

1 голос
/ 31 августа 2011

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

where var1 = :var1

и если все переменные, кроме var2 и var5, не равны нулю, вы получите

where var2 = :var2 and var5 = :var5

Это верно?

Если это так, то делайте то, что вы планируете делать, и динамически создавайте запрос, используя запрос критерия. Нечто подобное должно быть сделано:

CriteriaBuilder builder = em.getCriteriaBuilder();
Predicate conjunction = builder.conjunction();
if (var1 != null) {
    conjunction = builder.and(conjunction,
                              builder.equal(root.get(MyEntity_.var1),
                                            var1));
}
if (var2 != null) {
    conjunction = builder.and(conjunction,
                              builder.equal(root.get(MyEntity_.var2),
                                            var2));
}
...
criteria.where(conjunction);
0 голосов
/ 31 августа 2011

Вы не указываете тип объектов, которые хотите передать. Так что в этом примере я рассматриваю, что вы передадите Object .

@Test(expected=IllegalArgumentException.class)
public void testMyMethod() {
    List<Object> testList = new ArrayList<Object>();
    testList.add("1");
    testList.add("2");
    testList.add(3);

    myMethod(testList);
}

public void myMethod(List<Object> limitedList) {
    final int MAX_SIZE = 2;
    if (limitedList.size() > MAX_SIZE) {
        throw new IllegalArgumentException("Size exceeded");
    }
    //my logic
}

В этом примере я передаю аргументы в виде списка объектов, но вы можете использовать массив ( varargs ) или другой тип коллекции, если вам нужно. Если клиент отправит мне больше ожидаемых объектов, он выдаст исключение IllegalArgumentException .

Также, если вы не хотите генерировать исключение, вы можете просто продолжить и повторить список, чтобы связать параметры, но используя размер списка или MAX_SIZE в качестве ограничения. Например:

public void myMethod2(List<Object> limitedList) {
        final int MAX_SIZE = 2;

        int size = MAX_SIZE;
        if (limitedList.size() < MAX_SIZE) {
            size = limitedList.size();
        }

        //Iterate through the list
        for (int i = 0; i < size; i++) {
            Object obj = limitedList.get(i);
            //Logic to bind the obj to the criteria.            
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...