2012-06-12 48 views
0

我正在使用jqgrid插件的spring MVC 3.0。我正在構建jqgrid的搜索功能,它發送一個json對象到服務器端。我創建了一個虛擬java類來解析jqgrid的json,無論何時觸發搜索。所有這一切都很好。hibernate標準查詢 - 子屬性的屬性

我正在動態創建我的標準查詢,因爲用戶可以自由選擇搜索條件(等於,不等於,等等)。這裏是jqgrid發送的json字符串的一個例子。

{ 
    "groupOp": "AND", 
    "rules": [{ 
     "field": "company", 
     "op": "cn", 
     "data": "School"}, 
    { 
     "field": "numberOfStudents", 
     "op": "eq", 
     "data": "2"}] 
}​ 

此OS用作模板來解析此JSON

public class JsonJqgridSearchModel { 

    public String groupOp; 

    public ArrayList<JqgridSearchCriteria> rules; 
} 

通知稱爲JqgridSearchCriteria類型的Java類,這是它簡單地返回一個限制我隨時調用其getRestriction()方法的類。這裏是JqgridSearchCriteria

public class JqgridSearchCriteria { 

    public String field; 

    public String op; 

    public String data; 

    public SimpleExpression getRestriction(){ 
     if(op.equals("cn")){ 
      return Restrictions.like(field, data, MatchMode.ANYWHERE); 
     }else if(op.equals("eq")){ 
      return Restrictions.eq(field, data); 
     }else if(op.equals("ne")){ 
      return Restrictions.ne(field, data); 
     }else if(op.equals("lt")){ 
      return Restrictions.lt(field, data); 
     }else if(op.equals("le")){ 
      return Restrictions.le(field, data); 
     }else if(op.equals("gt")){ 
      return Restrictions.gt(field, data); 
     }else if(op.equals("ge")){ 
      return Restrictions.ge(field, data); 
     }else{ 
      return null; 
     }  
    } 
} 

我不得不浪費一點時間以上序正確傳達我的問題。如果您觀察json字符串,您將看到爲什麼字段數據用於通過getRestriction()返回SimpleExpression。

這是事情,我有對象-A其中有對象B作爲參考。我從網格上得到的是Object-B.getName()因此有JqgridSearchCriteria其中field = Object-B.getName()而數據是用戶提供的名稱。當這個運行我得到一個異常如下:

內部錯誤 對不起,我們遇到了一個內部錯誤。 詳細 無法獲得通過tt.edu.sbcs.model.Organization.id org.hibernate.property.DirectPropertyAccessor $ DirectGetter.get(DirectPropertyAccessor.java:62) org.hibernate.tuple的反射吸氣字段值。 entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:230) org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3852) org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:3560) org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:204) org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:243) org.hibernate.type.EntityType.getIdentifier(EntityType.java:449 ) org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:142) org.hibernate.loader.Loader.bindPositionalParameters(Loader.java:1789) org.hibernate.loader.Loader.bindParameterValues(Loader.java:1760 ) 。 。 。

下面是所有相關內容的摘錄。

Criteria criteria = session.createCriteria(CorporateRegistration.class); 
Iterator<JqgridSearchCriteria> iterator = jsonJqgridSearchModel.rules.iterator(); 
String operation = jsonJqgridSearchModel.groupOp; 
if(operation.equals("AND")){ 
    Conjunction conjunction = Restrictions.conjunction(); 
    while(iterator.hasNext()){ 
     conjunction.add(iterator.next().getRestriction()); 
    }   
    criteria.add(conjunction); 
}//conjunctions are for AND operation 
else{ 
    Disjunction disjunction = Restrictions.disjunction(); 
    while(iterator.hasNext()){ 
     disjunction.add(iterator.next().getRestriction()); 
    }   
    criteria.add(disjunction);   
}//disjunctions are for OR operations  
    for(Object o: criteria.list()){ 
     corpRegList.add((CorporateRegistration)o); 
    } 

我也嘗試過搜索數字,但是會傳遞的值是一個字符串。 我是否使用標準的createAlias? 當我返回SimpleExpression時,可以指定稱爲數據的屬性的數據類型嗎?

請指教。

回答

0

對於那些可能正在尋找答案的人,我使用了一個子標準。也就是說,如果您有一個稱爲A的標準,對於這些類型的情況,您可以說A.createCriteria(field).add(conjunction); 其中字段是指擁有實體中的實際屬性。這是我創建的一個功能,允許使用更具通用性的項目特定搜索邏輯。所以當你撥打A.list()你很好。它有點長,但很容易理解。

public class JqgridSearchCriteria { 

    public String field; 

    public String op; 

    public String data; 

    public String dataType; 

    public String dataProperty; 

    public SimpleExpression getSimpleExpression(String myField, Object o){ 
     if(op.equals("cn")){ 
      return Restrictions.like(myField, o.toString(), MatchMode.ANYWHERE); 
     }else if(op.equals("eq")){ 
      return Restrictions.eq(myField, o); 
     }else if(op.equals("ne")){ 
      return Restrictions.ne(myField, o); 
     }else if(op.equals("lt")){ 
      return Restrictions.lt(myField, o); 
     }else if(op.equals("le")){ 
      return Restrictions.le(myField, o); 
     }else if(op.equals("gt")){ 
      return Restrictions.gt(myField, o); 
     }else if(op.equals("ge")){ 
      return Restrictions.ge(myField, o); 
     }else{ 
      return null; 
     }  
    } 

    public void addMyRestriction(String groupOperation, Criteria criteria){ 
     Conjunction conjunction = Restrictions.conjunction(); 
     Disjunction disjunction = Restrictions.disjunction(); 
     if(groupOperation.equals("AND")){ 
      if(dataType.isEmpty()){ 
       conjunction.add(this.getSimpleExpression(field, data)); 
       criteria.add(conjunction); 
      }else{ 
       if(dataType.equals("Calendar")){ 
        try{ 
         DateFormat formatter = new SimpleDateFormat("MMMM dd, yyyy"); 
         Date date = (Date)formatter.parse(data); 
         Calendar cal = Calendar.getInstance(); 
         cal.setTime(date); 
         conjunction.add(this.getSimpleExpression(field, cal)); 
         criteria.add(conjunction); 
        }catch (ParseException e){ 
         System.out.println("Exception :"+e); 
        }     //used for calendar data types 
       }else if(dataType.equals("Long")){ 
        Long myLong = Long.parseLong(data); 
        conjunction.add(this.getSimpleExpression(field, myLong)); 
        criteria.add(conjunction); 
             //used for Long data types 
       }else if(dataType.equals("Integer")){ 
        Integer myInt = Integer.parseInt(data); 
        conjunction.add(this.getSimpleExpression(field, myInt)); 
        criteria.add(conjunction); 
             //used for Integer data types 
       }else{ 
        conjunction.add(this.getSimpleExpression(dataProperty, data)); 
        criteria.createCriteria(field).add(conjunction); 
       }      //used for custom or project specific data types 
      }// AND operation used conjunctions 
     }else{ 
      if(dataType.isEmpty()){ 
       disjunction.add(this.getSimpleExpression(field, data)); 
       criteria.add(disjunction); 
      }else{ 

       if(dataType.equals("Calendar")){ 
        try{ 
         DateFormat formatter = new SimpleDateFormat("MMMM dd, yyyy"); 
         Date date = (Date)formatter.parse(data); 
         Calendar cal = Calendar.getInstance(); 
         cal.setTime(date); 
         disjunction.add(this.getSimpleExpression(field, cal)); 
         criteria.add(disjunction); 
        }catch (ParseException e){ 
         System.out.println("Exception :"+e); 
        } 
       }else if(dataType.equals("Long")){ 
        Long myLong = Long.parseLong(data); 
        disjunction.add(this.getSimpleExpression(field, myLong)); 
        criteria.add(disjunction); 
       }else if(dataType.equals("Integer")){ 
        Integer myInt = Integer.parseInt(data); 
        disjunction.add(this.getSimpleExpression(field, myInt)); 
        criteria.add(disjunction); 
       }else{ 
        disjunction.add(this.getSimpleExpression(dataProperty, data)); 
        criteria.createCriteria(field).add(disjunction); 
       } 
      }   
     }// OR operation used disjunctions 
    } 
} 
0

關於搜索數字,我認爲你需要在你的JqgridSearchCriteria類中使用「type」屬性。例如,在用戶界面中,您可能需要定製可用的操作符,以便用戶不能爲數字值選擇「包含」。

在我們剛剛開發的類似系統中,我們使用['string','number','date']作爲搜索值類型。用戶可以選擇用於搜索的每一列都有一個類型,以便我們可以使用javascript來呈現適當的運算符列表。

這意味着您將知道在構建標準時正確地投射搜索條件值。它增加了應用程序的複雜性,但我沒有看到任何替代方案。