2013-08-01 32 views
2

我已閱讀其他帖子和有關如何使用「Where」子句「創建」括號語句的文檔。Ormlite如果問題與括號,構建元層查詢庫

我的要求很簡單:

... WHERE companyID=1 AND (director=true OR officer=true) ; 

我正在寫一個程序獲取Object的數組,然後將其分析爲Ormlite哪裏調用。一個典型的調用如下所示:

.., "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或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對象,但我仍然得到一個: 「你忘了一個與或OR?「信息。

我試圖創造「新的」 Where子句用的QueryBuilder:

Where w1 = qb.where() ; 
//process w1 conditions... 
return where.query() ; 

這也將失敗或在我嘗試了各種組合生成不正確的SQL。任何有關如何讓(...)和(或)(...)方法正常工作的建議都將不勝感激。

順便說一句,一旦圖書館工作正常,我會把它作爲開放源代碼或捐贈給格雷或兩者。

在此先感謝。 安東尼

+0

看看這個發音:[ORMLite - 插入在連接where子句](http://stackoverflow.com/a/24505596/2653843) 這是非常可推薦的 – user2653843

+0

當你有多次調用' processWhere(...)'還有當只有一個? – Gray

回答

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)但具有相同的含義。