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;