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试图回答一个奥姆林式的问题感到震惊。我得到任何分数的唯一原因是来自奥姆利特的问题。他的答案通常都很好。:-)请务必编辑您的问题,删除或更正现已过时的“已解决”部分。