2

我已经阅读了有关如何使用“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'))

我从文档示例中了解到的关键是在嵌套的 and(...) 调用中使用实例的地方相同。这正是我正在做的,但我仍然收到“你忘记了 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。任何有关如何使 and(...) 和 or(...) 方法正常工作的建议将不胜感激。

顺便说一句,一旦图书馆正常工作,我会将其作为开源或捐赠给 Gray,或两者兼而有之。

提前致谢。安东尼

4

1 回答 1

0

我遇到了同样的问题并像这样解决了它:

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)但含义相同。

于 2016-09-27T11:18:01.910 回答