我已经阅读了其他关于如何使用"Where"子句"创建"括号语句的文章和文档。
我的要求很简单:
... WHERE companyID=1 AND (director=true OR officer=true) ;
我正在编写一个例程,它接受一个Object数组,然后将其解析为一个Ormlite Where调用。一个典型的调用如下:
.., "companyID", 1, Q.AND, Q.Bracket, "director", true, Q.OR, "officer", true, Q.Bracket)
其目的是加快简单查询的速度。不希望取代Ormlite的查询工具。这是顶部的一个简单的元层。
对于简单的查询来说,一切都很好,因为参数是按顺序处理的,where子句是增量构建的。
对于括号,我将推迟处理,直到括号闭合。
这就是我的问题所在。我使用的文档中的示例显示:
-- From the OrmLite docs...
Where<Account, String> where = queryBuilder.where();
where.or(
where.and(
where.eq(Account.NAME_FIELD_NAME, "foo"),
where.eq(Account.PASSWORD_FIELD_NAME, "_secret")),
where.and(
where.eq(Account.NAME_FIELD_NAME, "bar"),
where.eq(Account.PASSWORD_FIELD_NAME, "qwerty")));
This produces the following approximate SQL:
SELECT * FROM account
WHERE ((name = 'foo' AND password = '_secret')
OR (name = 'bar' AND password = 'qwerty'))
我从docs示例中了解到的关键一点是,嵌套和(…)调用中使用了相同的where实例。这正是我正在做的事情,但我仍然收到一条"你忘了AND或or了吗"的信息。
实现"延迟"处理的代码如下所示:
@SuppressWarnings("unchecked")
private void processWhere(Where<?, ?> where, Q q, List<QValue> list)
{
if (null == list || list.size() < 2)
{
System.err.println("Invalid where passed: " + list);
return;
}
if (q.equals(Q.AND))
where.and(getCondition(where, list.get(0)), getCondition(where, list.get(1)));
else
where.or(getCondition(where, list.get(0)), getCondition(where, list.get(1)));
}
"QValue"项只是列、条件和值数据的"持有者"。
"getCondition"方法如下:
@SuppressWarnings("rawtypes")
protected Where getCondition(Where<?, ?> where, QValue qv)
{
if (null != where && null != qv)
return getCondition(where, qv.getType(), qv.getColumn(), qv.getValue(), qv.getValue2());
else
return null;
}
@SuppressWarnings("rawtypes")
protected Where getCondition(Where<?, ?> where, Q cond, String key, Object val, Object val2)
{
if (null == where || null == cond || null == key || null == val)
return null;
SelectArg arg = new SelectArg();
arg.setValue(val);
try
{
switch (cond)
{
case NotNull:
where.isNotNull(key);
break;
case IsNull:
where.isNull(key);
break;
case Equals:
where.eq(key, arg);
break;
case NotEqual:
where.ne(key, arg);
break;
case GreaterThan:
where.gt(key, arg);
break;
case LessThan:
where.lt(key, arg);
break;
case Like:
arg.setValue("%" + val + "%");
where.like(key, arg);
break;
case LikeStart:
arg.setValue("" + val + "%");
where.like(key, arg);
break;
case LikeEnd:
arg.setValue("%" + val);
where.like(key, arg);
break;
case Between:
if (null != val && null != val2)
where.between(key, val, val2);
break;
default:
where.eq(key, arg);
break;
}
}
catch (SQLException e)
{
GlobalConfig.log(e, true);
return null;
}
return where;
}
据我所知,我正确地使用了Where对象,但我仍然得到了一个:"你忘了AND或or了吗?"信息。
我尝试过用QueryBuilder:创建"新的"Where子句
Where w1 = qb.where() ;
//process w1 conditions...
return where.query() ;
在我尝试过的各种组合中,它也会失败或生成不正确的SQL。任何关于如何使和(…)和或(…)方法正常工作的建议都将不胜感激。
顺便说一句,一旦图书馆正常工作,我会把它作为开源或捐赠给格雷,或者两者兼而有之。
提前谢谢。Anthony
我遇到了同样的问题,并像这样解决了它:
where.eq("companyID", 1);
where.and(where, where.or(where.eq("director", true), where.eq("officer", true)));
或
where.and(where.eq("companyID", 1), where.or(where.eq("director", true), where.eq("officer", true)));
SQL中的
((`companyID` = 1 AND `director` = 1 ) OR (`companyID` = 1 AND `officer` = 1 ))
它与示例子句WHERE companyID=1 AND (director=true OR officer=true)
不同,但具有相同的含义。