Ormlite括号出现问题时,正在构建元层查询库



我已经阅读了其他关于如何使用"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)不同,但具有相同的含义。