2012-06-12 51 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来呈现适当的运算符列表。

这意味着您将知道在构建标准时正确地投射搜索条件值。它增加了应用程序的复杂性,但我没有看到任何替代方案。