我正在使用基于 JPA 類的投影來構建 DTO。DTO 代表一篇文章。它有一個title欄位和一個isWrittenByMe欄位。當引數作者是文章的作者之一時,該isWrittenByMe欄位應保持,否則。truefalse
我創建了一個 JPA 存盤庫并添加了一個執行自定義 JPQL 查詢的方法。
@Query("SELECT new com.example.learnjpql.dto.ArticleDTO(a.title, :author MEMBER OF a.authors) FROM Article a")
List<ArticleDTO> getAllArticles(Author author);
Hibernate 生成了這個查詢
Hibernate: select article0_.title as col_0_0_, ? in (authors1_.author_id) as col_1_0_ from article article0_ cross join article_authors2 authors1_ where article0_.id=authors1_.article_id
這是 的輸出getAllArticles。
[ArticleDTO[title=Article 1, isAuthoredByMe=true], ArticleDTO[title=Article 1, isAuthoredByMe=false], ArticleDTO[title=Article 2, isAuthoredByMe=true], ArticleDTO[title=Article 3, isAuthoredByMe=false], ArticleDTO[title=Article 3, isAuthoredByMe=false], ArticleDTO[title=Article 4, isAuthoredByMe=false], ArticleDTO[title=Article 4, isAuthoredByMe=false], ArticleDTO[title=Article 5, isAuthoredByMe=false]]
它正在輸出連接表中的所有條目,但我想要表中的Article條目
例如,如果引數作者寫過文章 1 和文章 3,我想要一個回傳如下內容的查詢:
| 標題 | 是我寫的 |
|---|---|
| 第1條 | true |
| 第二條 | false |
| 第三條 | true |
| 第四條 | false |
| 第五條 | false |
我想也許不是傳遞:author MEMBER OF a.authors給建構式,而是傳遞一個 SELECT 陳述句,這將為每個條目運行一個單獨的查詢,但我得到了一個意外的令牌錯誤。
如果我遺漏了什么或使用了錯誤的工具,請告訴我。
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
public class Author {
@Id
private Long id;
private String firstname;
private String lastname;
@ManyToMany(fetch = FetchType.EAGER, mappedBy = "authors")
private Set<Article> articles;
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Author author))
return false;
return getId().equals(author.getId()) && getFirstname().equals(author.getFirstname()) && getLastname().equals(author.getLastname());
}
@Override
public int hashCode() {
return Objects.hash(getId(), getFirstname(), getLastname());
}
public String toString() {
return "Author(id=" this.getId() ", firstname=" this.getFirstname() ", lastname=" this.getLastname();
}
}
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@ToString
public class Article {
@Id
private Long id;
private String title;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "article_authors2",
joinColumns = { @JoinColumn(name = "article_id") },
inverseJoinColumns = { @JoinColumn(name = "author_id") })
private Set<Author> authors;
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof Article article))
return false;
return getId().equals(article.getId()) && getTitle().equals(article.getTitle());
}
@Override
public int hashCode() {
return Objects.hash(getId(), getTitle());
}
}
public record ArticleDTO(
String title,
boolean isAuthoredByMe
) { }
uj5u.com熱心網友回復:
在 Hibernate 6 之前,謂詞不能用作運算式,所以你必須將你的謂詞包裝成case when ... then true else false endie 你的查詢變成:
@Query("SELECT new com.example.learnjpql.dto.ArticleDTO(a.title, case when :author MEMBER OF a.authors then true else false end) FROM Article a")
List<ArticleDTO> getAllArticles(Author author);
或者,您也可以使用顯式子查詢:
@Query("SELECT new com.example.learnjpql.dto.ArticleDTO(a.title, case when exists (select 1 from a.authors sub where sub = :author) then true else false end) FROM Article a")
List<ArticleDTO> getAllArticles(Author author);
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/515523.html
標籤:爪哇春天休眠jpa
