2013-03-07 4 views
1

생성 된 Q * 클래스와 java reflexion을 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); 
} 

이 잘 작동하지만 나 또한 (TABLENAME + "1000") 어색한 위해서, newInstance를 제거하는 것입니다 내 다른 질문 https://stackoverflow.com/questions/15269845/querydsl-extract-table-name-from-predicate-booleanexpression-object)에 대한 답변 대신 PathBuilder을 사용하는 것이 좋습니다했다.

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) 나는() NOTLIKE을 (좋아 지금은하지만 EQ() 또는 관계에 네브라스카()를 호출 할 수 있습니다) 2) 어떻게 colObj를받을 수 있나요 . 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%");