带有计数字段的 JPQL ManyToMany 查询
JPQL ManyToMany query with count field
我在具有 spring 安全性的 spring 引导应用程序中的两个实体(用户和电影)之间存在多对多关系。
我想创建一个 REST API 来查找所有电影并包含一个新字段,显示登录用户是否看过电影。
我找不到简单的方法,我只找到了在查询中创建新 DTO 对象的解决方案。接下来我展示我的代码。
实体如下:
电影:
@Entity
@Table(name = "movies")
public class Movies implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@NotNull
@Size(max = 100)
@Column(name = "name", length = 100, nullable = false)
private String name;
@Column(name = "jhi_year")
private Long year;
@Size(max = 100)
@Column(name = "category", length = 100)
private String category;
@ManyToMany(mappedBy = "movies")
@JsonIgnore
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<User> users = new HashSet<>();
用户:
@Entity
@Table(name = "user")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@Size(max = 50)
@Column(name = "login", length = 50)
private String login;
@Size(max = 250)
@Column(name = "bio", length = 250)
private String bio;
@ManyToMany
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JoinTable(name = "user_movies",
joinColumns = @JoinColumn(name="user_id", referencedColumnName="id"),
inverseJoinColumns = @JoinColumn(name="movies_id", referencedColumnName="id"))
我所做的是一个 @Repository class 和一个像这样的 JPQL @query:
@Query("select new com.test.service.dto.MoviesDTO(movies.id, movies.name, movies.year, movies.category, " +
" count(users.id)) from Movies movies left join movies.users users on users.login = ?#{principal.username} group by movies.id ")
Page<MoviesDTO> findAll(Pageable pageable);
这很好用,但是有更简单的方法吗?最好找到一种方法来执行此操作,在实体 class 中添加一个新对象,避免在查询中创建一个新的 DTO 对象。
我知道这和我自己前段时间发的 this one 几乎是同一个问题,这对我来说仍然是个谜。
非常非常感谢!
感谢 jasarez 的回答。我为投影更改了 DOT,效果非常好!
存储库:
@Query("select movies.id as id, movies.name as name, movies.year as year, movies.category as category, count(users.id) as moviesCount " +
"from Movies movies left join movies.users users on users.login = ?#{principal.username} group by movies.id")
Page<MovieWithUserData> findAllWithUserData(Pageable pageable);
和投影:
public interface MovieWithUserData {
Long getId();
String getName();
String getCategory();
Integer getYear();
Long getMoviesCount();
}
我在具有 spring 安全性的 spring 引导应用程序中的两个实体(用户和电影)之间存在多对多关系。
我想创建一个 REST API 来查找所有电影并包含一个新字段,显示登录用户是否看过电影。
我找不到简单的方法,我只找到了在查询中创建新 DTO 对象的解决方案。接下来我展示我的代码。
实体如下:
电影:
@Entity
@Table(name = "movies")
public class Movies implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@NotNull
@Size(max = 100)
@Column(name = "name", length = 100, nullable = false)
private String name;
@Column(name = "jhi_year")
private Long year;
@Size(max = 100)
@Column(name = "category", length = 100)
private String category;
@ManyToMany(mappedBy = "movies")
@JsonIgnore
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<User> users = new HashSet<>();
用户:
@Entity
@Table(name = "user")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@Size(max = 50)
@Column(name = "login", length = 50)
private String login;
@Size(max = 250)
@Column(name = "bio", length = 250)
private String bio;
@ManyToMany
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JoinTable(name = "user_movies",
joinColumns = @JoinColumn(name="user_id", referencedColumnName="id"),
inverseJoinColumns = @JoinColumn(name="movies_id", referencedColumnName="id"))
我所做的是一个 @Repository class 和一个像这样的 JPQL @query:
@Query("select new com.test.service.dto.MoviesDTO(movies.id, movies.name, movies.year, movies.category, " +
" count(users.id)) from Movies movies left join movies.users users on users.login = ?#{principal.username} group by movies.id ")
Page<MoviesDTO> findAll(Pageable pageable);
这很好用,但是有更简单的方法吗?最好找到一种方法来执行此操作,在实体 class 中添加一个新对象,避免在查询中创建一个新的 DTO 对象。
我知道这和我自己前段时间发的 this one 几乎是同一个问题,这对我来说仍然是个谜。
非常非常感谢!
感谢 jasarez 的回答。我为投影更改了 DOT,效果非常好!
存储库:
@Query("select movies.id as id, movies.name as name, movies.year as year, movies.category as category, count(users.id) as moviesCount " +
"from Movies movies left join movies.users users on users.login = ?#{principal.username} group by movies.id")
Page<MovieWithUserData> findAllWithUserData(Pageable pageable);
和投影:
public interface MovieWithUserData {
Long getId();
String getName();
String getCategory();
Integer getYear();
Long getMoviesCount();
}