如何通过JQL直接找到多个实体的交集?

时间:2016-11-07 19:44:17

标签: java sql jpa

这些是我的模型类:

Film.java

@Entity
public class Film {

    private Integer id;
    private String title;
    private List<FilmActor> filmActors;

    @OneToMany(mappedBy = "film")
    public List<FilmActor> getFilmActors() {
        return filmActors;
    }

    public void setFilmActors(List<FilmActor> filmActors) {
        this.filmActors = filmActors;
    }
}

Actor.java

@Entity
public class Actor {

    private Integer id;
    private String firstname;
    private String lastname;

    private List<FilmActor> filmActors;

    @OneToMany(mappedBy = "actor")
    public List<FilmActor> getFilmActors() {
        return filmActors;
    }

    public void setFilmActors(List<FilmActor> filmActors) {
        this.filmActors = filmActors;
    }
}

这是加入表实体:

@Entity
@Table(name = "film_actor")
public class FilmActor {

    private FilmActorPK id;

    private Film film;
    private Actor actor;
    private Timestamp lastUpdate;

    @EmbeddedId
    public FilmActorPK getId() {
        return id;
    }

    public void setId(FilmActorPK id) {
        this.id = id;
    }

    @ManyToOne
    @MapsId("film")
    @JoinColumn(name = "film_id")
    public Film getFilm() {
        return film;
    }

    public void setFilm(Film film) {
        this.film = film;
    }

    @ManyToOne
    @MapsId("actor")
    @JoinColumn(name = "actor_id")
    public Actor getActor() {
        return actor;
    }

    public void setActor(Actor actor) {
        this.actor = actor;
    }

    @Column(name = "last_update")
    public Timestamp getLastUpdate() {
        return lastUpdate;
    }

    public void setLastUpdate(Timestamp lastUpdate) {
        this.lastUpdate = lastUpdate;
    }
}

和主键类:

@Embeddable
public class FilmActorPK implements Serializable {

    private int actorId;
    private int filmId;

    @Column(name = "actor_id")
    public int getActorId() {
        return actorId;
    }

    public void setActorId(int actorId) {
        this.actorId = actorId;
    }

    @Column(name = "film_id")
    public int getFilmId() {
        return filmId;
    }

    public void setFilmId(int filmId) {
        this.filmId = filmId;
    }
}

所以我想找到2个演员扮演的电影。这就是我所拥有的:

@Override
public Collection<Film> filmsActorsTogether(Actor a, Actor b) {
    final List<Film> filmsOfActorA = filmsOfActor(a);
    final List<Film> filmsOfActorB = filmsOfActor(b);
    final Collection<Film> intersection = CollectionUtils.intersection(filmsOfActorA, filmsOfActorB);
    return intersection;
}

@Override
public List<Film> filmsOfActor(Actor actor) {
    final EntityManager entityManager = persistenceUtil.getEntityManager();
    final Actor persistentActor = entityManager.find(Actor.class, actor.getId());
    final ArrayList<Film> films = new ArrayList<Film>();
    for (FilmActor filmActor : persistentActor.getFilmActors()) {
        films.add(filmActor.getFilm());
    }
    entityManager.close();
    return films;
}

有没有办法在没有获取2个演员的所有电影,并在内存中使用过滤的情况下实现这一目标?如何使用JQL直接从DB获取影片?

1 个答案:

答案 0 :(得分:1)

也许有更优雅的东西,但以下查询应该有效:

select f from Film f where 
   (select count(fa.id) from FilmActor fa 
           where fa.film = f 
             and (fa.actor = :actor1 or fa.actor = :actor2)) = 2 

旁注:你的PK类应该有一个正确的equals()和hashCode()方法