是否可以撰寫一個包含多個自定義建構式的TypedQuery?例如,如果你想創建包含一個id和另一個物件的物件,如:
TypedQuery<ChapterWithBookId> query = em.createQuery(
"SELECT new " ChapterWithBookId.class.getName() " (book.id, new example.Chapter(chapter.id, "
"chapter.size"
")"
" FROM " Book.class. getName() " AS book JOIN " Chapter.class.getName() " AS chapter where "
"book.id IN :ids", ChapterWithBookIds.class)
.setParameter("ids", ids);
不管這個例子是否有實際意義,這個查詢應該回傳一個ChapterWithBookId型別的物件的串列,在這個串列中,所有書籍的每一章都有一個物件,這個物件包含在作為引數設定的id串列中。
uj5u.com熱心網友回復:
沒錯,在JPQL中你不能有兩個建構式的呼叫--它不是Java,而是一種自定義語言,只支持 "SELECT NEW"。
有幾種方法可以補救這個問題:
.1.
.1. 讓你的構造器也構建第二個物件--當然,這是一個丑陋的黑客:
.1.
public ChapterWithBookId(Long bookId, Long chapterId, Long size) {
this.bookId = bookId。
this.chapter = new Chapter(chapterId, size);
}
.2. 只需將結果作為一個元組回傳,遍歷元組串列并建立物件(也很難看)。
。.3. 如果你使用 Hibernate,請使用 Hibernate 的 ResultTransformer:
.3.
List<ChapterWithBookId> chapterWithBookDtos= entityManager
.createQuery(
"SELECT book.id, chapter.id, chapter.size"
"FROM " Book.class. getName() " AS book JOIN " Chapter.class.getName() " AS chapter where "
"book.id IN :ids", ChapterWithBookIds.class)
.setParameter("ids", ids);)
.unwrap( org.hibernate.query.class )
.setResultTransformer(
new ResultTransformer() {
@Override
公共 Object transformTuple(
Object[] tuple,
字串[] 別名) {
return new ChapterWithBookId(
(Long) tuple[0]。
new Chapter((Long) tuple[1], (Long) tuple[2] )
);
}
@Override[/span
public List transformList(List collection) {
return collection。
}
}
)
.getResultList()。
這里有一篇關于你的選擇的一般文章。Hibernate 4, 5 & 6 中的 ResultTransformer
Vlad Mihalcea 發表了一篇關于ResultTransformer 也能提高查詢效率的博文。
而且 Vlad 還提供了hibernate-types 庫,它有一個好得多的 ListResultTransformer。
我絕對推薦最后兩篇文章和Vlad所寫的一切--博客和書。
uj5u.com熱心網友回復:
正如JPA規范中所定義的那樣(見4.8 SELECT Clause節):
SELECT子句的語法如下:SELECT子句的語法如下:
select_clause :: = SELECT [DISTINCT] select_item {, select_item}* select_item ::= select_expression [ [AS] result_variable] select_expression::= single_valued_path_expression | 標量運算式| 聚合運算式 | identification_variable | 識別_變數| OBJECT(identification_variable)| 建構式_運算式 constructor_expression ::= 建構式_expression new constructor_name ( constructor_item {, constructor_item}* ) constructor_item ::= single_valued_path_expression| 標量運算式| 聚合運算式 | 識別變數 aggregate_expression ::= 識別變數 { AVG | MAX | MIN | SUM } ([DISTINCT] state_valued_path_expression)| COUNT ([DISTINCT] identification_variable | state_valued_path_expression |) single_valued_object_path_expression) | 函式_invocation
所以,你可以看到constructor_item不能成為constructor_expression。但是你可以很容易地重構你的類ChapterWithBookId建構式,通過id和size來構造example.Chapter,而且,IMHO,這將使JPQL更容易閱讀。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/309825.html
標籤:
