0

我正在使用带有 jqgrid 插件的 spring MVC 3.0。我正在为 jqgrid 构建搜索功能,它将一个 json 对象发送到服务器端。每当触发搜索时,我创建了一个虚拟 java 类来解析 jqgrid 的 json。到目前为止,一切都很好。

我正在动态创建我的条件查询,因为用户可以自由选择搜索条件(相等,不相等,......等)。下面是 jqgrid 发送的 json 字符串的示例。

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

这是用作模板来解析此 JSON 的 Java 类:

public class JsonJqgridSearchModel {

    public String groupOp;

    public ArrayList<JqgridSearchCriteria> rules;
}

注意名为 JqgridSearchCriteria 的类型。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。

事情是这样的:我有Object-A,它有Object-B作为参考。我从网格中得到的是Object-B.getName()因此有一个JqgridSearchCriteriawhere field=Object-B.getName()并且数据是用户提供的名称。当它运行时,我得到一个异常如下:

Internal Error
Sorry, we encountered an internal error.
Details
could not get a field value by reflection getter of 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 时指定名为 data 的属性的数据类型吗?

4

2 回答 2

0

对于那些可能正在寻找答案的人,我使用了一个子标准。也就是说,如果您有一个称为A的标准,对于这些类型的情况,您可以说A.createCriteria(field).add(conjunction); where 字段指的是拥有实体中的实际属性。这是我创建的内容,以允许更通用的特定于项目的搜索逻辑。所以当你打电话时,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
    }
}
于 2012-06-22T17:21:27.563 回答
0

关于搜索数字,我认为您将需要 JqgridSearchCriteria 类上的“类型”属性。此外,在 UI 中,您可能希望定制可用的运算符,例如,用户不能为数值选择“包含”。

在我们刚刚开发的类似系统中,我们使用 ['string', 'number', 'date'] 作为搜索值类型。用户可以选择进行搜索的每一列都有一个类型,以便我们可以使用 javascript 来显示适当的运算符列表。

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

于 2012-06-13T14:26:21.400 回答