2013-03-07 93 views
1

一种方法是动态构建一个Predicate列表,稍后传递给数据库服务对象。为了创建基于谓词列表的表连接,我需要确定每个谓词的基础生成类Q *。在Predicate上调用getType()getClass()并没有帮助。QueryDSL:从谓词(布尔表达式)对象中提取表名

这是我建立的谓词:

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); 

查询建筑代码:

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); 
+0

哪个Querydsl你正在使用模块,JPA,SQL还是其他? – 2013-03-07 11:31:46

+0

我正在使用JPA。生成的Q *类扩展com.mysema.query.types.path.EntityPathBase – 2013-03-07 11:46:05

回答

2

不要使用生成的Q-类型的动态表达创作。您可以使用动态路径,而不是http://www.querydsl.com/static/querydsl/2.9.0/reference/html/ch03.html#d0e1379

在你的情况是这样的

Class<?> entityType = Class.forName(...) 
PathBuilder entityPath = new PathBuilder(entityType, "entity"); 
PathBuilder relation = entityPath.get("relation"); 
Predicate predicate = relation.get...(...).eq(...) 

对于路径提取使用这个类http://www.querydsl.com/static/querydsl/2.9.0/apidocs/com/mysema/query/types/PathExtractor.html

PathExtactor提取第一路出给定Expression

+0

这是一个很好的提示,我将切换到使用PathBuilder。然而,我的问题仍然存在 - 如何找出JPAQuery.from(X).leftJoin(...)中使用哪个表? – 2013-03-07 12:51:01

+0

在JPA中,您并不真正将表连接到表,而是类到类,所以您剩余的问题似乎是如何将表映射到类映射。我会查看JPA元模型的所有实体类型,并从中创建一个表到实体图。 – 2013-03-07 13:01:26

+0

我想你让我在PathExtractor的正确轨道上。我仍然无法将我的Java反射代码转换为PathBuilder版本。我刚刚创建了一个新的问题,希望你有时间回答:http://stackoverflow.com/questions/15273542/querydsl-generate-predicate-from-pathbuilder – 2013-03-07 14:19:08