问题
A method is dynamically building a list of Predicate
s that is later passed to a database service object. In order to create table joins based on the predicate list I need to determine the underlying generated class Q* of each predicate. Calling getType()
or getClass()
on the Predicate doesn't help.
This is how I build the predicates:
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);
// method name is one of eq, ne, like...
Method m = colObj.getClass().getMethod(methodName, classParam );
return (Predicate) m.invoke(colObj, operand);
The query building code:
JPAQuery query = new JPAQuery(entityManager);
query = query.from(company);
for(Predicate p : predicates){
// if there's at least one predicat with the underlying db class Foo:
query = query.join(company.foos, new QFoo());
break;
}
List<Object[]> rows = query.where(predicates.toArray(new Predicate[0])).listDistinct(company.id);
回答1:
Don't use the generated Q-types for dynamic Expression creation. You can use dynamic paths instead http://www.querydsl.com/static/querydsl/2.9.0/reference/html/ch03.html#d0e1379
In your case something like this
Class<?> entityType = Class.forName(...)
PathBuilder entityPath = new PathBuilder(entityType, "entity");
PathBuilder relation = entityPath.get("relation");
Predicate predicate = relation.get...(...).eq(...)
For Path extraction use this class http://www.querydsl.com/static/querydsl/2.9.0/apidocs/com/mysema/query/types/PathExtractor.html
PathExtactor
extracts the first path out of a given Expression
来源:https://stackoverflow.com/questions/15269845/querydsl-extract-table-name-from-predicate-booleanexpression-object