Java ORMLite中的多个、组合或条件

Java ORMLite中的多个、组合或条件,java,ormlite,Java,Ormlite,我喜欢这样的查询: select data from table where (x > 1 and x < 100) or (x > 250 and x < 300) 从表中选择数据 其中(x>1和x250和x

我喜欢这样的查询:

select data from table
 where (x > 1 and x < 100)
    or (x > 250 and x < 300)
从表中选择数据
其中(x>1和x<100)
或(x>250和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)
)
final QueryBuilder qb=QueryBuilder();
最终式,其中w=qb.Where();
w、 或(
w、 gt(“x”,1)和().lt(“x”,100),
w、 gt(“x”,250)和().lt(“x”,300)
)
如果事先知道这些条件,那就太好了&在编码时,我需要动态添加这些条件

基本上,这种方法
public com.j256.ormlite.stmt.Where或(com.j256.ormlite.stmt.Where left,com.j256.ormlite.stmt.Where right,com.j256.ormlite.stmt.Where…其他)
是不够的。 它需要另一个
方法来支持
Where
条件的
ArrayList


谢谢你的建议。

你明白声明的
..
部分是什么意思吗?这意味着您可以传入一个数组(如果您只指定值,编译器将为您构造一个数组)

因此,如果需要,只需创建一个列表,然后将其转换为数组(除第一个条件外的所有条件),然后调用该方法。您可能希望使用静态方法轻松完成最后一部分:

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);
}
公共静态无效或(如果目标,
列表条件)
{
//TODO:参数验证
其中first=conditions.get(0);
其中,second=条件。get(1);
List rest=conditions.subList(2,conditions.size());
//由于泛型,您将无法在此处抑制警告。。。
其中[]restArray=rest.toArray(新的,其中[0]);
目标。其中(第一,第二,重新排列);
}
如果事先知道这些条件,那就太好了&在编码时,我需要动态添加这些条件

Where.or(Where left,Where right,Where…others)
中有点语法漏洞。当你打电话时:

w.or(
    w.gt("x", 1).and().lt("x", 100),
    w.gt("x", 250).and().lt("x", 300)
);
或()

w.or(w, w);
您确实可以将其改写为:

w.gt("x", 1).and().lt("x", 100);
w.gt("x", 250).and().lt("x", 300);
w.or(w, w);
那里的
方法只使用参数来计算需要从堆栈中弹出多少子句。当您调用
gt
lt
等时,它会将项目推送到子句堆栈上。
和()。我们进行这些语法攻击是因为我们希望支持线性、链式和基于参数的查询:

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

w.gt("x", 1).and().lt("x", 100);
w.and(w.gt("x", 1), w.lt("x", 100));
但这意味着您有能力通过使用该方法极大地简化代码。因此,在上面的
示例中,也可以是:

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);
因此,您根本不需要
条件
列表。你只需要一个柜台。所以你可以这样做:

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()
并跳过
子句。请注意,如果只添加一个子句,则可以完全跳过
方法调用

哦,下面的说法是行不通的:


因为
target
first
是同一个对象
first.getStatement()谢谢你,乔恩。我试过你的例子,现在它说:
找不到符号方法或(com.j256.ormlite.stmt.Where,com.j256.ormlite.stmt.Where[])
目标.Where
部分。@SebastianRoth:好的,看起来我误读了签名-这是第三个参数。不过想法是一样的。将编辑…谢谢Jon,基本上你的建议是正确的。我看这比它应该的复杂得多。如果只有一个元素,或者只有两个元素,这个想法将无法正常工作。我将编辑并将我的版本放在那里。这似乎需要对ORMlite进行更改。@SebastianRoth:您可以轻松地调整此实用程序方法以处理1个元素,并且它应该已经可以处理2个元素(通过空数组)。另一方面,我同意在ORMlite中进行更改以使其更简单是有用的。一些问题仍然存在,某些组合会创建无效的查询。我将尝试与奥姆莱特公司的格雷联系,讨论这个问题。这真是太棒了!感谢您提供关于ORMlite的背景信息以及解释和帮助。愉快地删除代码和复杂性。非常感谢。很高兴帮助塞巴斯蒂安。事实上,我对@Jon试图回答一个奥姆林式的问题感到震惊。我得到任何分数的唯一原因是来自奥姆利特的问题。他的答案通常都很好。:-)请务必编辑您的问题,删除或更正现已过时的“已解决”部分。