我喜欢这样的查询:
select data from table
where (x > 1 and x < 100)
or (x > 250 and x < 300)
在ORMlite中,可以使用此代码:
final QueryBuilder<Data,Integer> qb = queryBuilder();
final Where<Data, Integer> w = qb.where();
w.or(
w.gt("x", 1).and().lt("x", 100),
w.gt("x", 250).and().lt("x", 300)
)
如果事先了解情况,那就太好了。在编码时,我需要动态添加条件。
基本上,方法public com.j256.ormlite.stmt.Where<T,ID> or(com.j256.ormlite.stmt.Where<T,ID> left, com.j256.ormlite.stmt.Where<T,ID> right, com.j256.ormlite.stmt.Where<T,ID>... others)
是不够的。
它需要另一种支持or
ArrayList
条件的Where
方法。
感谢您的任何建议。
答案 0 :(得分:22)
如果事先了解情况,那就太好了。在编码时,我需要动态添加条件。
在ORMLite Where.or(Where<T, ID> left, Where<T, ID> right, Where<T, ID>... others)
中有点语法黑客攻击。当你打电话:
w.or(
w.gt("x", 1).and().lt("x", 100),
w.gt("x", 250).and().lt("x", 300)
);
or()
方法得到的是:
w.or(w, w);
你真的可以把它重写为:
w.gt("x", 1).and().lt("x", 100);
w.gt("x", 250).and().lt("x", 300);
w.or(w, w);
or
方法只使用参数来计算从堆栈中弹出多少个子句。当您调用gt
和lt
以及其他人时,它会推送子句堆栈上的项目。 and()
方法将1个项目从堆栈中拉出,然后在将来获取另一个项目。我们做这些语法黑客,因为我们想支持线性,链接和基于参数的查询:
w.gt("x", 1);
w.and();
w.lt("x", 100);
与
w.gt("x", 1).and().lt("x", 100);
与
w.and(w.gt("x", 1), w.lt("x", 100));
但这意味着您可以使用Where.or(int many)方法极大地简化代码。所以在上面的or
示例中也可以是:
w.gt("x", 1).and().lt("x", 100);
w.gt("x", 250).and().lt("x", 300);
// create an OR statement from the last 2 clauses on the stack
w.or(2);
所以你根本不需要conditions
列表。你需要的只是一个柜台。所以你可以这样做:
int clauseC = 0;
for (int i : values) {
if (i == 1) {
w.le(C_PREIS, 1000);
clauseC++;
} else if (i == 2) {
w.gt(C_PREIS, 1000).and().le(C_PREIS, 2500);
clauseC++;
} else if (i == 3) {
w.gt(C_PREIS, 2500).and().le(C_PREIS, 5000);
clauseC++;
} else if (i == 4) {
w.gt(C_PREIS, 5000).and().le(C_PREIS, 10000);
clauseC++;
} else if (i == 5) {
w.gt(C_PREIS, 10000);
clauseC++;
}
}
// create one big OR(...) statement with all of the clauses pushed above
if (clauseC > 1) {
w.or(clauseC);
}
如果i
只能是1到5,那么您可以使用values.size()
并跳过clauseC
。请注意,如果我们只添加一个子句,那么我们可以完全跳过OR
方法调用。
哦,以下声明将不工作:
target.or().raw(first.getStatement());
因为target
和first
是同一个对象。 first.getStatement()
转储整个SQL WHERE
子句,我认为这不是你想要的。
答案 1 :(得分:2)
您了解声明的...
部分是什么意思吗?这意味着您可以传入数组(如果您只是指定值,编译器将为您构造一个数组)。
如果需要,只需创建一个列表,然后将其转换为数组(除了第一个条件之外的所有条件),然后调用该方法。您可能希望使用静态方法轻松完成最后一部分:
public static <T, ID> void or(Where<T, ID> target,
List<Where<T, ID>> conditions)
{
// TODO: Argument validation
Where<T, ID> first = conditions.get(0);
Where<T, ID> second = conditions.get(1);
List<Where<T, ID>> rest = conditions.subList(2, conditions.size());
// You'll to suppress a warning here due to generics...
Where<T, ID>[] restArray = rest.toArray(new Where[0]);
target.where(first, second, restArray);
}