2013-03-07 85 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