在 Spring Boot JPA 中以多对多关系访问@JoinTable
Accessing @JoinTable in many-to-many relationship in Springboot JPA
我创建了一个 API,其中包含演员、电影和类别实体。演员和电影通过映射到名为 movie_actor 的连接 table 的多对多关系连接,类别通过一对多关系与电影连接。
我正在尝试编写一个本机查询,该查询 return 是一个整数,表示来自特定演员播放过的特定类别的电影数量,例如查询将 return 2如果演员出演了 2 部不同的科幻电影。从数据库级别执行此操作没有问题,我可以看到连接 table movie_actor 但是 table 在我的 api 中仍然无法访问,因为它不是一个单独的实体。我如何创建它以自动将演员和电影 ID 映射为 movie_actor table?
这是一个在 H2 数据库中适用于我的示例代码:
SELECT COUNT(*) FROM MOVIE M JOIN MOVIE_ACTOR MA on M.MOVIE_ID = MA.MOVIE_ID WHERE ACTOR_ID = 1 AND CATEGORY_ID = 1
这是我的实体:
演员:
@Entity
@Data
@Table(name = "actor")
@AllArgsConstructor
@NoArgsConstructor
public class Actor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "actor_id")
private long actorId;
@Column(name = "name")
private String name;
@Column(name = "surname")
private String surname;
@Nullable
@ManyToMany(mappedBy = "actors", fetch = FetchType.EAGER)
@JsonBackReference
private List<Movie> movies = new ArrayList<>();
public Actor(String name, String surname){
this.name = name;
this.surname = surname;
}
}
电影:
@Entity
@Data
@Table(name = "movie")
@AllArgsConstructor
@NoArgsConstructor
public class Movie {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "movie_id")
private long movieId;
@Column(name = "title")
private String title;
@ManyToMany
@JoinTable(
name = "movie_actor",
joinColumns = @JoinColumn(name = "movie_id"),
inverseJoinColumns = {@JoinColumn(name = "actor_id")}
)
@JsonManagedReference
private List<Actor> actors = new ArrayList<>();
@ManyToOne
@JoinColumn(name = "CATEGORY_ID")
@JsonManagedReference
private Category category;
}
因此您必须在 API 中使其可访问。一种选择是将交集 table movie_actor
映射到实体 MovieActor
并将 Actor
和 Movie
之间的 ManyToMany
关系拆分为 OneToMany
与 MovieActor
的关系,如:
@Entity
@Data
@Table(name = "movie_actor")
@AllArgsConstructor
@NoArgsConstructor
public class MovieActor {
@EmbeddedId
private MovieActorId productOrderId = new MovieActorId();
@ManyToOne(cascade = CascadeType.ALL, optional = false)
@MapsId("movieId")
@JoinColumn(name = "product_id", nullable = false)
private Movie movie;
@ManyToOne(cascade = CascadeType.ALL, optional = false)
@MapsId("actorId")
@JoinColumn(name = "order_id", nullable = false)
private Actor actor;
public void addMovieActor(Movie aMovie, Actor aActor) {
movie = aMovie;
actor = aActor;
aMovie.getMovieActors().add(this);
aActor.getMovieActors().add(this);
}
}
@Embeddable
@Getter
@Setter
public class MovieActorId implements Serializable {
@Column(name = "movie_id")
private Long movieId;
@Column(name = "actor_id")
private Long actorId;
}
@Entity
@Data
@Table(name = "actor")
@AllArgsConstructor
@NoArgsConstructor
public class Actor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "actor_id")
private long actorId;
@OneToMany(mappedBy = "actor")
private List<MovieActor> movieActors = new ArrayList<>();
}
@Entity
@Data
@Table(name = "movie")
@AllArgsConstructor
@NoArgsConstructor
public class Movie {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "movie_id")
private long movieId;
@OneToMany(mappedBy = "movie")
private List<MovieActor> movieActors = new ArrayList<>();
}
现在您可以在查询中访问交集 table MovieActor
。如果需要,您甚至可以向此 table 添加更多列。
我创建了一个 API,其中包含演员、电影和类别实体。演员和电影通过映射到名为 movie_actor 的连接 table 的多对多关系连接,类别通过一对多关系与电影连接。
我正在尝试编写一个本机查询,该查询 return 是一个整数,表示来自特定演员播放过的特定类别的电影数量,例如查询将 return 2如果演员出演了 2 部不同的科幻电影。从数据库级别执行此操作没有问题,我可以看到连接 table movie_actor 但是 table 在我的 api 中仍然无法访问,因为它不是一个单独的实体。我如何创建它以自动将演员和电影 ID 映射为 movie_actor table?
这是一个在 H2 数据库中适用于我的示例代码:
SELECT COUNT(*) FROM MOVIE M JOIN MOVIE_ACTOR MA on M.MOVIE_ID = MA.MOVIE_ID WHERE ACTOR_ID = 1 AND CATEGORY_ID = 1
这是我的实体:
演员:
@Entity
@Data
@Table(name = "actor")
@AllArgsConstructor
@NoArgsConstructor
public class Actor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "actor_id")
private long actorId;
@Column(name = "name")
private String name;
@Column(name = "surname")
private String surname;
@Nullable
@ManyToMany(mappedBy = "actors", fetch = FetchType.EAGER)
@JsonBackReference
private List<Movie> movies = new ArrayList<>();
public Actor(String name, String surname){
this.name = name;
this.surname = surname;
}
}
电影:
@Entity
@Data
@Table(name = "movie")
@AllArgsConstructor
@NoArgsConstructor
public class Movie {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "movie_id")
private long movieId;
@Column(name = "title")
private String title;
@ManyToMany
@JoinTable(
name = "movie_actor",
joinColumns = @JoinColumn(name = "movie_id"),
inverseJoinColumns = {@JoinColumn(name = "actor_id")}
)
@JsonManagedReference
private List<Actor> actors = new ArrayList<>();
@ManyToOne
@JoinColumn(name = "CATEGORY_ID")
@JsonManagedReference
private Category category;
}
因此您必须在 API 中使其可访问。一种选择是将交集 table movie_actor
映射到实体 MovieActor
并将 Actor
和 Movie
之间的 ManyToMany
关系拆分为 OneToMany
与 MovieActor
的关系,如:
@Entity
@Data
@Table(name = "movie_actor")
@AllArgsConstructor
@NoArgsConstructor
public class MovieActor {
@EmbeddedId
private MovieActorId productOrderId = new MovieActorId();
@ManyToOne(cascade = CascadeType.ALL, optional = false)
@MapsId("movieId")
@JoinColumn(name = "product_id", nullable = false)
private Movie movie;
@ManyToOne(cascade = CascadeType.ALL, optional = false)
@MapsId("actorId")
@JoinColumn(name = "order_id", nullable = false)
private Actor actor;
public void addMovieActor(Movie aMovie, Actor aActor) {
movie = aMovie;
actor = aActor;
aMovie.getMovieActors().add(this);
aActor.getMovieActors().add(this);
}
}
@Embeddable
@Getter
@Setter
public class MovieActorId implements Serializable {
@Column(name = "movie_id")
private Long movieId;
@Column(name = "actor_id")
private Long actorId;
}
@Entity
@Data
@Table(name = "actor")
@AllArgsConstructor
@NoArgsConstructor
public class Actor {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "actor_id")
private long actorId;
@OneToMany(mappedBy = "actor")
private List<MovieActor> movieActors = new ArrayList<>();
}
@Entity
@Data
@Table(name = "movie")
@AllArgsConstructor
@NoArgsConstructor
public class Movie {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "movie_id")
private long movieId;
@OneToMany(mappedBy = "movie")
private List<MovieActor> movieActors = new ArrayList<>();
}
现在您可以在查询中访问交集 table MovieActor
。如果需要,您甚至可以向此 table 添加更多列。