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

标签 java sql jpa

这些是我的模型类:

电影.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 个 Actor 的所有电影并在内存中使用过滤的情况下实现此目的?如何使用 JQL 直接从数据库获取影片?

最佳答案

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

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() 方法

关于java - 如何直接通过JQL找到多对多实体的交集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40473316/

相关文章:

java - 使用不带 @GeneratedValue 注释的 JPA 实体 ID

java - 在封闭范围内定义的局部变量 log 必须是最终的或有效最终的

sql - 显式与隐式 SQL 连接

java - 黑莓应用程序自动更新

MYSQL 多列 COUNT DISTINCT

sql - 使用 COUNT 的多重选择语句

jpa - @IdClass JPA 注释

spring - 使用 Spring Data : column $COLUMN_NAME is of type timestamp without time zone but expression is of type bytea 的 postgres 中的时间戳错误

java - 工厂方法如何返回接口(interface)和抽象类的实例?

java.lang.错误: Unresolved compilation error: Unreachable code for loop