Spring boot “我有一个问题”;你也可以喜欢;Spring boot JPA中的功能
我想为博客创建一个简单的“你可能也喜欢”功能。 有很多帖子,每个帖子都有一个或多个标签。标签也可以包含许多帖子。我想实现一个功能,在这里你可以打开一篇文章,并向你推荐带有类似标签的文章 因此,我创建了3个实体: Post.javaSpring boot “我有一个问题”;你也可以喜欢;Spring boot JPA中的功能,spring-boot,hibernate,jpa,Spring Boot,Hibernate,Jpa,我想为博客创建一个简单的“你可能也喜欢”功能。 有很多帖子,每个帖子都有一个或多个标签。标签也可以包含许多帖子。我想实现一个功能,在这里你可以打开一篇文章,并向你推荐带有类似标签的文章 因此,我创建了3个实体: Post.java @Entity @Table public class Post { @Id @Column @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
@Entity
@Table
public class Post {
@Id
@Column
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String text;
@Column
private String author;
@OneToMany(mappedBy = "post")
Set<PostTags> postTags;
public Post(){}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Set<PostTags> getPostTags() {
return postTags;
}
public void setPostTags(Set<PostTags> postTags) {
this.postTags = postTags;
}
}
和存储库:
@Repository
public interface PostTagsRepository extends JpaRepository<PostTags, Long> {
@Query("select p.post from PostTags p where p.tag.id IN :tagIds")
Set<Post> findPostsbyTagIds (List<Long> tagIds);
}
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
@Query("select p from Post p where p.author = :author")
Set<Post> findPostsByAuthor(String author);
}
等等。。。
因此,这不是一个选择。那么如何正确保存标记呢?还是我的实体创建不正确?我犯了什么错?谢谢大家! 我不太明白
标签
作为一个实体背后的想法
我的看法是,您使用postTags
并将其更改为tags
。如果要以其他方式限制用户或字符串集,则此标记将是一组枚举。之后,我将添加一个端点,该端点根据标签或标签列表返回post,您可能也喜欢功能。该端点只向数据库发出请求(查找标记包含givenTag max 10的帖子)。最后,您只有一个实体:
@Entity
@Table
public class Post {
@Id
@Column
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String text;
@Column
private String author;
@Column
@Convert(converter = StringListConverter.class)
Set<String> tags;
// ...
}
@实体
@桌子
公营职位{
@身份证
@纵队
@GeneratedValue(策略=GenerationType.IDENTITY)
私人长id;
@纵队
私有字符串文本;
@纵队
私有字符串作者;
@纵队
@Convert(converter=StringListConverter.class)
设置标签;
// ...
}
转换器实施感谢您的帮助。但是你能再给我一次提示吗?要选择post by标记,我必须使用本机查询,因为我无法正确编写jpql查询。所以这个查询工作:@query(value=“SELECT*FROM post WHEREtags
LIKE%:tag%或author
LIKE%:author%”,nativeQuery=true)设置findPostsByTagsAndAuthor(String tag,String author);所以如何在jpql中编写它,因为我尝试了这个:查询(“从Post p where:tagin(p.tags)”中选择p),但它不起作用,因为它要求p.tags不是一个集合。如果你帮我,我会很高兴的!谢谢这里的问题是p.tags
只是一个字符串而不是子查询。这就是
中的不起作用的原因。如果您真的想在
中使用,我刚刚发现@ElementCollection
可以工作。基本上,它会生成另一个表来存储列表。这样,您就可以在
中创建一个连接表,后跟一个。谢谢你的回复,我也尝试了这个选项,它创建了另一个表,所以它不适合我。所以我决定继续使用本机查询
@Repository
public interface PostTagsRepository extends JpaRepository<PostTags, Long> {
@Query("select p.post from PostTags p where p.tag.id IN :tagIds")
Set<Post> findPostsbyTagIds (List<Long> tagIds);
}
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
@Query("select p from Post p where p.author = :author")
Set<Post> findPostsByAuthor(String author);
}
@GetMapping("/posts")
public Set<Post> showRecommendedPosts(){
//Imitate post id
long postId = 1;
Post postFound = postRepository.findById(postId).get();
Set<PostTags> postTags = postFound.getPostTags();
List<Long> listTagIds = new ArrayList<>();
//extract ids of the tags from the post
for(PostTags tag : postTags){
listTagIds.add(tag.getTag().getId());
}
//find posts by Author
Set<Post> postsByAuthor = postRepository.findPostsByAuthor(postFound.getAuthor());
//find posts by Tags
Set<Post> postsByTagIds = postTagsRepository.findPostsbyTagIds(listTagIds);
//We combine both sets
Set<Post> recommendedPosts = new HashSet<>(postsByAuthor);
recommendedPosts.addAll(postsByTagIds);
recommendedPosts.remove(postFound);
return recommendedPosts;
}
PostTags newPostTag1 = new PostTags();
newPostTag.setPost(post1);
newPostTag.setTag(tag1);
PostTags newPostTag2 = new PostTags();
newPostTag2.setPost(post1);
newPostTag2.setTag(tag2);
PostTags newPostTag3 = new PostTags();
newPostTag3.setPost(post1);
newPostTag3.setTag(tag3);
@Entity
@Table
public class Post {
@Id
@Column
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String text;
@Column
private String author;
@Column
@Convert(converter = StringListConverter.class)
Set<String> tags;
// ...
}