[英]Spring Data JPA - Many to many query
我有两个实体 Person 和 Movie。
@Entity
public class Person {
..some fields
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "actors")
@OrderBy("id")
private Set<Movie> moviesActor = new TreeSet<>();
}
@Entity
public class Movie {
..fields
@JoinTable(name = "actor_movie",
joinColumns = { @JoinColumn(name = "movie_id") },
inverseJoinColumns = { @JoinColumn(name = "actor_id") })
private Set<Person> actors = new TreeSet<>();
}
存在多对多关系,因此有新表 actor_movie 来保留它。 我怎样才能让每个人都拥有任何电影? 所以我想要实现的是获取 actor_movie 表中存在的每个人。 我尝试使用 Spring data jpa 但找不到正确的查询。
实体关系的最佳实践:
fetch = FetchType.LAZY
。JOIN FETCH
Query。LazyInitializationException
。spring.jpa.open-in-view=false
例子:
由 Spring Data JPA 和 Hibernate 作为 JPA 提供者。
实体:
public class Blog{
...
@ManyToMany(fetch = FetchType.LAZY) //default is LAZY in ManyToMany
@JoinTable(name="blog_tag",
joinColumns = @JoinColumn(name = "blog_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id"))
@OrderBy //order by tag id
private Set<Tag> tags = new HashSet<>();
//2 utility methods in owner side
public void addTag(Tag tag){
tags.add(tag);
tag.getBlogs().add(this);
}
public void removeTag(Tag tag){
tags.remove(tag);
tag.getBlogs().remove(this);
}
//override equals & hashcode
}
public class Tag {
...
@ManyToMany(mappedBy = "tags")
private Set<Blog> blogs = new HashSet<>();
//override equals & hashcode
}
现在假设,您想要获取一个包含标签项的博客:
存储库:
@Repository
public interface BlogRepository extends JpaRepository<Blog, Long> {
@Query("select b from Blog b join fetch b.tags where b.name = :name")
Blog getBlog(@Param("name") String blogName);
}
服务:
public interface BlogService {
Blog getBlog(String blogName);
}
@Service
public class BlogServiceImpl implements BlogService{
@Autowired
private BlogRepository blogRepository;
@Override
public Blog getBlog(String blogName) {
return blogRepository.getBlog(blogName);
}
}
由于您使用的是 Fetch 类型lazy,因此您需要使用join fetch 来获取moviesActor。
您可以将 jpql 与 spring 数据一起使用。 我没有测试下面的查询,但应该可以工作。
public interface PersonRepository extends JpaRepository<Person, Long> { //Long if Person.id is of type Long
@Query("SELECT p FROM Person p LEFT JOIN FETCH p.moviesActor WHERE size(p.moviesActor) > 0");
List<Person> findActors1();
// Or
@Query("SELECT p FROM Person p JOIN FETCH p.moviesActor");
List<Person> findActors2();
}
有关 jpql size() 运算符的更多信息: https ://www.thoughts-on-java.org/jpql/
您可以直接使用 join :
@Query("SELECT p FROM Person p JOIN p.moviesActor movie");
列表 findPersonHasMovie();
您只需要在 Person 和 Movie 之间进行一次JOIN
。 由于 Hibernate 抽象了中间表的存在,因此您无需担心它。
因此,使用 Spring Data Repository:
class PersonRepository extends CrudRepository<Person, Long> {
List<Person> findByMoviesActor();
}
使用 Jpql:
SELECT person FROM Person person JOIN person.moviesActor movie
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.