本文介绍了QueryDSL:从 PathBuilder 生成谓词的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何用PathBuilder替换下面使用生成的Q*类和java反射的方法?

How to replace the following method that uses the generated Q* class and java reflexion with a PathBuilder?

// member vars:
T operand;  // can be a BigDecimal or a String
String tableName;
String fieldName;
String methodName;

public Predicate asPredicate()
{
   Class<?> tableClazz = Class.forName("foo.bar.database.model.Q"+ WordUtils.capitalize(tableName));
   Object tableObj = tableClazz.getConstructor(String.class).newInstance(tableName +"1000");
   Field colField = tableClazz.getDeclaredField(fieldName);
   Object colObj = colField.get(tableObj);

   Class classParam = Object.class;
   if(methodName.matches(".*like"){
     classParam = String.class;
   }
   // method name is one of eq, ne, like...
   Method m = colObj.getClass().getMethod(methodName, classParam );
   return (Predicate) m.invoke(colObj, operand);
}

这很有效,但我被建议在回答我的另一个问题时改用 PathBuilder https://stackoverflow.com/questions/15269845/querydsl-extract-table-name-from-predicate-booleanexpression-object) 这也将删除尴尬的 newInstance(tableName +"1000").

this works well but I was advised to use PathBuilder instead in an answer to my other question https://stackoverflow.com/questions/15269845/querydsl-extract-table-name-from-predicate-booleanexpression-object) which would also remove the awkward newInstance(tableName +"1000").

PathBuilder<?> entityPath = new PathBuilder("foo.bar.database.model.Q"+ WordUtils.capitalize(tableName), "entity"); // what does the second param stand for?
PathBuilder relation = entityPath.get(fieldName);
// ???

两个问题:1) 我现在可以在关系上调用 eq() 或 ne() 但不能调用 like(), notLike()2) 我如何获得 colObj 以便我可以使用 java 反射 colObj.getClass().getMethod(...)

two problems:1) I can call eq() or ne() on relation now but not like(), notLike()2) how do I get colObj so that I can use java reflection colObj.getClass().getMethod(...)

解决方案:感谢 Timo 的回答,除了两个 instanceof 条件之外,我完全放弃了反射,现在使用此代码:

solution:Thanks to Timo's answer I have ditched the reflexion altogether except for the two instanceof conditions and use this code now:

tableClazz = Class.forName("foo.bar.database.model."+ WordUtils.capitalize(tableName));
PathBuilder<?> entityPath = new PathBuilder(tableClazz, tableName +"1000");
Predicate predicate = null;

if(operand instanceof String){
   StringPath path = entityPath.getString(fieldName);
   switch(type){
       case EQ:
          predicate = path.eq((String) operand);
       case CONTAINS:
          predicate = path.like("%" + operand +"%");
          break;
      // snip BEGINS WITH, ENDS WITH
    }
}else if(operand instanceof BigDecimal){
    assert(type.equals(Type.EQ));
    NumberPath<BigDecimal> path = entityPath.getNumber(fieldName, BigDecimal.class);
    predicate = path.eq((BigDecimal) operand);
}
if(negation){
  return predicate.not();
}
return predicate;

推荐答案

你应该这样使用它

// entityClass is the entity type, not the Q-type
Class<?> entityClass = Class.forName(...)
// "entity" is the variable name of the path
PathBuilder<?> entityPath = new PathBuilder(entityClass, "entity"); 
// use getString to get a String path
Predicate predicate = entityPath.getString("property").like("a%");

这篇关于QueryDSL:从 PathBuilder 生成谓词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-15 14:47