简体   繁体   English

将varargs从Java代码传递到SQL或PL / SQL

[英]Pass varargs from Java code to SQL or PL/SQL

I need to bind at maximum 8 variables. 我最多需要绑定8个变量。 Each one of them could be null . 它们每个都可以为null Is there any recommended way to achieve this? 有什么推荐的方法可以做到这一点吗? I know that I could simply check for null , but this seems tedious. 我知道我可以简单地检查null ,但这似乎很乏味。

Additional details : 其他详细信息
I'm going to call this sql from java code. 我将从Java代码中调用此sql。 It may be written using JPA 2.0 Criteria API , but most likely it's going to be a native query. 它可以使用JPA 2.0 Criteria API编写,但是很可能它将是本机查询。 The database is Oracle 10g , so I think I could make use of PL/SQL as well. 数据库是Oracle 10g ,因此我认为我也可以使用PL / SQL

Edit1: 编辑1:
Maybe the title is a bit misleading, so I'll try to elaborate. 也许标题有点误导,所以我会尽力阐述。 The resulting SQL would be something like: 产生的SQL将类似于:
...
WHERE var1 = :var1
AND var2 = :var2
...
AND var = :var8

Now I need to bind parameters from java code in the way like: 现在,我需要以如下方式绑定Java代码中的参数:
nativeQuery.setParameter("var1", var1)
...
nativeQuery.setParameter("var8", var8)

Some parameters could be null, so there is no need to bind them. 一些参数可以为null,因此无需绑定它们。 But I see no way I can omit them in SQL. 但是我看不出我可以在SQL中省略它们。

Edit2: I'm expecting to see SQL or PL/SQL procedure in your answers (if it's ever possible without null checking). Edit2:我希望在您的答案中看到SQL或PL / SQL过程(如果没有检查就可以的话)。 In fact, all of these variables are of the same type. 实际上,所有这些变量都是同一类型。 I think it's not possible to find a solution using ANSI SQL, but maybe there are some PL/SQL procedures which allow to work with varargs? 我认为不可能找到使用ANSI SQL的解决方案,但是也许有一些PL / SQL过程可以与varargs一起使用?

The use of a criteria query is appropriate in this case, because if I understood correctly, you need to construct the SQL query dynamically. 在这种情况下,使用条件查询是合适的,因为如果我理解正确,则需要动态构造SQL查询。 If all the variables except var1 are null, the where clause would be 如果除var1之外的所有变量均为null,则where子句为

where var1 = :var1

and if all variables except var2 and var5 are non null you would have 如果除var2和var5以外的所有变量都不为null,您将拥有

where var2 = :var2 and var5 = :var5

Is that right? 那正确吗?

If so, then do what you plan to do, and construct the query dynamically using a criteria query. 如果是这样,则按照计划进行操作,并使用条件查询动态构建查询。 Something like this must be done: 必须执行以下操作:

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);

You don't specify the type of the objects you want to pass. 您没有指定要传递的对象的类型。 So in this example I'm considering you will pass Object . 因此,在此示例中,我考虑您将传递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
}

In this example I'm passing the arguments as a List of Objects but you could use array ( varargs ) or another type of collection if you need to. 在此示例中,我将参数作为对象列表传递,但是如果需要,可以使用数组( varargs )或其他类型的集合。 If the client sends me more than the expected objects it will throw an IllegalArgumentException . 如果客户端向我发送了超出预期对象的对象,它将抛出IllegalArgumentException

Also if you don't want to throw an exception you could just continue and iterate the list to bind the parameters but using the list size or MAX_SIZE as your limit. 另外,如果您不想引发异常,则可以继续并迭代列表以绑定参数,但可以使用列表大小或MAX_SIZE作为限制。 For example: 例如:

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.            
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM