我使用spring MVC 3.0和jqgrid插件。我正在为jqgrid构建搜索功能,它将json对象发送到服务器端。每当触发搜索时,我都创建了一个虚拟java类来解析jqgrid的json。一切都很顺利。
我正在动态创建我的条件查询,因为用户可以自由选择搜索条件(等于,不等于......等)。以下是jqgrid发送的json字符串的示例。
{
"groupOp": "AND",
"rules": [{
"field": "company",
"op": "cn",
"data": "School"},
{
"field": "numberOfStudents",
"op": "eq",
"data": "2"}]
}
这个os用作解析这个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(),因此有一个JqgridSearchCriteria
,其中 field = Object-B.getName(),数据是用户提供的名称。当这个运行时,我得到一个例外如下:
内部错误 抱歉,我们遇到了内部错误。 细节 无法通过tt.edu.sbcs.model.Organization.id的反射getter获取字段值 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的属性的数据类型?
请指教。
答案 0 :(得分:0)
关于搜索数字,我认为你的JqgridSearchCriteria类需要一个“type”属性。同样在UI中,您可能希望定制可用的运算符,以便用户无法为数值选择“包含”,例如。
在我们开发的类似系统中,我们使用['string','number','date']作为搜索值类型。用户可以选择用于搜索的每一列都有一个类型,以便我们可以使用javascript来显示适当的运算符列表。
这意味着您将在构建条件时知道正确地转换搜索条件值。它增加了应用程序的复杂性,但我没有看到任何替代方案。
答案 1 :(得分:0)
对于那些可能正在寻找答案的人,我使用了一个子标准。如果你有一个名为 A 的标准,对于这些类型的情况你可以说A.createCriteria(field).add(conjunction);
其中field是指拥有实体中的实际属性。以下是我创建的内容,以允许更具通用性的项目特定搜索逻辑。所以当你致电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
}
}