2013-03-07 121 views
1

如何將以下使用生成的Q *類和java反射的方法替換爲PathBuilder?QueryDSL:從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(表名+「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(),但現在不喜歡(),notLike() 2)我怎麼colObj,這樣我可以使用Java反射。colObj.getClass()getMethod(...)

解決方案: 由於蒂莫的答案,我已經完全拋棄了反思,除了這兩個條件的instanceof而現在使用此代碼:

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; 

回答

7

你應該這樣使用它

// 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%");