ORMLite中的多个组合OR条件

Seb*_*oth 11 java ormlite

我喜欢这样的查询:

select data from table
 where (x > 1 and x < 100)
    or (x > 250 and x < 300)
Run Code Online (Sandbox Code Playgroud)

在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)
)
Run Code Online (Sandbox Code Playgroud)

虽然如果事先知道条件并且在编码时这很好,我需要动态添加条件.

基本上这种方法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支持的方法ArrayListWhere条件.

谢谢你的任何建议.

Gra*_*ray 23

虽然如果事先知道条件并且在编码时这很好,我需要动态添加条件.

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)
);
Run Code Online (Sandbox Code Playgroud)

or()方法得到的是:

w.or(w, w);
Run Code Online (Sandbox Code Playgroud)

你真的可以把它重写为:

w.gt("x", 1).and().lt("x", 100);
w.gt("x", 250).and().lt("x", 300);
w.or(w, w);
Run Code Online (Sandbox Code Playgroud)

or那里的方法只使用参数来计算从堆栈中弹出多少个子句.当你打电话gt,并lt和其他人,其在推的条款堆项目.该and()方法将1个项目从堆栈中拉出,然后在将来再使用另一个项目.我们做这些语法黑客,因为我们想支持线性,链接和基于参数的查询:

w.gt("x", 1);
w.and();
w.lt("x", 100);
Run Code Online (Sandbox Code Playgroud)

与:

w.gt("x", 1).and().lt("x", 100);
Run Code Online (Sandbox Code Playgroud)

与:

w.and(w.gt("x", 1), w.lt("x", 100));
Run Code Online (Sandbox Code Playgroud)

但这意味着您可以通过使用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);
Run Code Online (Sandbox Code Playgroud)

所以你根本不需要这个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);
}
Run Code Online (Sandbox Code Playgroud)

如果i只能是1到5那么你可以使用values.size()并跳过clauseC.请注意,如果我们只添加一个子句,那么我们可以OR完全跳过方法调用.

哦,下面的语句将无法正常工作:

target.or().raw(first.getStatement());
Run Code Online (Sandbox Code Playgroud)

因为targetfirst是同一个对象. first.getStatement()转储WHERE我认为不是你想要的整个SQL 子句.