[英]Criteria JPA 2 join many to many unidirectional realtion
我有兩個實體,電影和流派,從流派到電影具有多對多關系。 流派是關系的“父母”。
這會生成三個表: genre
、 movie
和genre_movie
@Entity
public class Genre {
@Id
@GeneratedValue(strategy = AUTO)
private Long id;
@ManyToMany(fetch = LAZY)
@JoinTable( name = "genre_movie",
joinColumns = {@JoinColumn(name = "genre_id")},
inverseJoinColumns = {@JoinColumn(name = "movie_id")}
)
private Set<Movie> movies = new HashSet<>();
...
}
@Entity
public class Movie {
@Id
@GeneratedValue(strategy = AUTO)
private Long id;
...
}
我可以使用條件查詢 api 執行此查詢嗎? 根據流派 ID 過濾電影。
select *
from movie
join genre_movie on movie.id = genre_movie.movie_id
where genre_id = 19;
在電影方面雙重映射您的 MovieGenre:
@ManyToMany(fetch = LAZY, mappedBy = "movies")
private Set<Genre> genres = new HashSet<>();
這不會創建額外的表,但(只是)使關聯在“電影端”上可用(對於 JPA);;)
..然后我們可以查詢(像往常一樣,未經測試):
-- e.g. JPQL:
select [distinct] movie
from Movie movie
join movie.genres genre
where genre.id = :pGenreId
..傳入Genre
ID。 或者:
select [distinct] movie
from Movie movie
where :pGenre member of movie.genres
...通過Genre
object(參數)。
也可以看看:
這是不可能的,因為 Movie 實體沒有對 Genre 的引用,因為它不是雙向的。
但是您可以重組查詢以獲得相同的結果:
Select * from genre
inner join genre_movie on genre.id = genre_movie.genre_id
inner join movie on genre_movie.movie_id = movie.id
where genre.genre_id = 19;
查詢將按如下方式實現:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Movie> cq = cb.createQuery(Movie.class);
Root<Genre> rootGenre = cq.from(Genre.class);
Join<Genre,Movie> joinMovie = rootGenre.join("movies");
//Join<Genre,Movie> joinMovie = rootGenre.join(Genre_.movies);
cq.select(joinMovie);
cq.where(cb.equals(rootGenre.get("id"), 19));
//cq.where(cb.equals(rootGenre.get(Genre_.id), 19));
return this.em.createQuery(cq).getResultList();
我特別推薦使用元模型(注釋行),因為在按字符串格式的名稱訪問屬性時,可能會出現錯誤,而元模型不在更復雜的查詢中。
我還認為將關系定義為雙向以便能夠將電影 class 設置為 Root 會很有趣
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.