【问题标题】:Spring Data Jpa and Specification - ManyToManySpring Data Jpa 和规范 - 多对多
【发布时间】:2017-10-28 23:10:52
【问题描述】:

我也有类似的问题:Spring Data Jpa and Specification - how to work with ManyToOne and ManyToMany relations?

我有 3 个表:actor、movie 和 macors(电影和演员的连接表)和 spring boot,hibernate-jpamodelgen

@Entity
public class Actor {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

...
}

@Entity
public class Movie implements BaseId {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
....

}

我想要那些有 2 位或更多演员一起出演的电影。类似这样的查询:

select * from movie 
    join mactors on movie.id = mactors.movie
    where mactors.actor = x and mactors.actor = y and ...;

public static Specification<Movie> findMoviesByActors(List<Long> actors) {
    return (root, criteriaQuery, criteriaBuilder) -> {
        ...
        return ...
    };
}

我不知道接下来会发生什么。

任何提示将不胜感激。 谢谢

【问题讨论】:

    标签: hibernate jpa spring-boot spring-data-jpa


    【解决方案1】:

    看来我原来的 SQL 查询是错误的。 一个有效的 SQL 将是:

    select distinct * from movie 
        join mactors on movie.id = mactors.movie_id 
        where mactors.actor_id in (x, y, z...)
    group by movie.title
    having count(movie.id) >= numberOfActors;
    

    下面的代码有效:

    public static Specification<Movie> findByActorsId(List<Long> actorIds) {
        return new Specification<Movie>() {
            @Override
            public Predicate toPredicate(Root<Movie> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Join<Movie, Actor> join = root.join(Movie_.actors);
    
                Predicate actorIdPredicate = cb.disjunction();
                for(Long aid : actorIds) {
                    actorIdPredicate.getExpressions().add(cb.equal(join.get(Actor_.id), aid));
                }
    
                Expression<Long> count = cb.count(root.get(Movie_.id));
                CriteriaQuery<Movie> q = (CriteriaQuery<Movie>) query.distinct(true).groupBy(root.get(Movie_.title)).
                        having(cb.greaterThanOrEqualTo(count, new Long(actorIds.size()));
    
                return actorIdPredicate;
            }
        };
    }
    

    我没有设法让 in 子句起作用,但我在循环中做了一个 OR...

    欢迎任何改进建议:)

    【讨论】:

      猜你喜欢
      • 2017-08-19
      • 2018-05-07
      • 2017-01-09
      • 2015-10-28
      • 2016-02-17
      • 2016-07-22
      • 2021-11-15
      • 1970-01-01
      • 2017-01-12
      相关资源
      最近更新 更多