【发布时间】:2020-06-23 17:41:45
【问题描述】:
我有一个与 post 和 post_cmets 表的一对多映射,我们的要求是只检索两个表中的几个值,然后像 postDTO 那样作为一对多映射发送回调用者。下面是我们的代码。
发布实体
@Entity(name = "Post")
@Getter
@Setter
public class Post {
@Id
private Long id;
private String title;
private LocalDateTime createdOn;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "post", orphanRemoval = true)
private List<PostComment> comments = new ArrayList<>();
public void addComment(PostComment comment) {
this.comments.add(comment);
comment.setPost(this);
}
}
PostCommentEntity
@Getter
@Setter
public class PostComment {
@Id
private Long id;
private String review;
private LocalDateTime createdOn;
public PostComment(String review) {
this.review = review;
this.createdOn = LocalDateTime.now();
}
@ManyToOne
private Post post;
}
postDTO --> 我们需要的响应格式。
@Getter
@Setter
@Builder
@ToString
public class PostDTO {
String title;
@Builder.Default
List<PostCommentsDTO> comments;
}
PostCommentsDTO --> 一对多嵌套投影值。
@Data
@Builder
public class PostCommentsDTO {
String review;
}
因为我们无法直接使用 spring data jpa 来实现这一点。使用替代映射实现。
PostRepository 我们只需要从 post 表中获取标题,并从 postcomment 表中获取所需的评论作为 postDTO 类,因为我们无法在单个实例中执行映射我在 Java 中委托映射如下创建中间投影。
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
@Query("SELECT p.title as title, c.review as review FROM Post p JOIN p.comments c where p.title = :title")
List<PostCommentProjection> findByTitle(@Param("title") String title);
}
PostCommentProjection
public interface PostCommentProjection {
String getTitle();
String getReview();
}
最后是Java
List<PostCommentProjection> postCommentProjections = this.postRepository.findByTitle("Post Title");
final Function<Entry<String, List<PostComments>>, PostDTO> mapToPostDTO = entry -> PostDTO.builder()
.title(entry.getKey()).comments(entry.getValue()).build();
final Function<PostCommentProjection, String> titleClassifier = PostCommentProjection::getTitle;
final Function<PostCommentProjection, PostComments> mapToPostComments = postCommentProjection -> PostComments
.builder().review(postCommentProjection.getReview()).build();
final Collector<PostCommentProjection, ?, List<PostComments>> downStreamCollector = Collectors
.mapping(mapToPostComments, Collectors.toList());
List<PostDTO> postDTOS = postCommentProjections.stream()
.collect(groupingBy(titleClassifier, downStreamCollector)).entrySet().stream().map(mapToPostDTO)
.collect(toUnmodifiableList());
是否有一种有效或自动的方法可以直接从存储库中获取 POSTDTO 项目?
【问题讨论】:
标签: java hibernate jpa spring-data-jpa