我需要绑定最多8个变量。其中每一个都可以 null 。 有没有推荐的方法来实现这一目标?我知道我可以简单地检查 null ,但这看起来很乏味。
其他详情:
我要从java代码中调用这个sql。它可以使用 JPA 2.0 Criteria API 编写,但很可能是原生查询。数据库是 Oracle 10g ,所以我想我也可以使用 PL / SQL 。
EDIT1:
也许标题有点误导,所以我会试着详细说明。
生成的SQL类似于:
...
WHERE var1 = :var1
AND var2 = :var2
...
AND var = :var8
现在我需要以类似的方式绑定java代码中的参数:
nativeQuery.setParameter("var1", var1)
...
nativeQuery.setParameter("var8", var8)
某些参数可能为null,因此无需绑定它们。但我认为我无法在SQL中省略它们。
EDIT2: 我期待在你的答案中看到SQL或PL / SQL程序(如果没有 null 检查就可以)。 实际上,所有这些变量都属于同一类型。我认为使用ANSI SQL找不到解决方案是不可能的,但也许有一些PL / SQL程序允许使用varargs?
答案 0 :(得分:1)
在这种情况下,使用条件查询是合适的,因为如果我理解正确,您需要动态构造SQL查询。如果除var1之外的所有变量都为null,则where子句将为
where var1 = :var1
如果除var2和var5之外的所有变量都是非null,那么你将拥有
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);
答案 1 :(得分:0)
您没有指定要传递的对象的类型。所以在这个例子中我认为你会传递对象。
@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.
}
}