数据库设计

文章标签的设计

理论上,文章post和标签tag是多对多的关系,这样需要一张关系表post_tag来维护两者的关系,因为tag表简单只有一个属性name,不如臆想成一个文章对应多个标签,这样一来,在牺牲少量空间的情况下可以少维护一张表,也更方便统计和操作。

JsonMappingException: Infinite recursion (StackOverflowError)

文章和作者之间时多对一关系

// Post.java 实体中有
    @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH}, optional = false)
    private User author;

// User.java实体中有
    @OneToMany(mappedBy = "author", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Set<Post> posts;

controller直接返回文章实体,则在解析成json时就会报上面的错误,解决的方法是在任意一个属性的get方法上加@JsonBackReference注解

    // 此注解避免Json解析时 post和author无限引用
    @JsonBackReference
    public User getAuthor() {
        return author;
    }

但是注意

@JsonBackReference和@JsonManagedReference:这两个标注通常配对使用,通常用在父子关系中。@JsonBackReference标注的属性在序列化(serialization,即将对象转换为json数据)时,会被忽略(即结果中的json数据不包含该属性的内容)。@JsonManagedReference标注的属性则会被序列化。在序列化时,@JsonBackReference的作用相当于@JsonIgnore,此时可以没有@JsonManagedReference。但在反序列化(deserialization,即json数据转换为对象)时,如果没有@JsonManagedReference,则不会自动注入@JsonBackReference标注的属性(被忽略的父或子);如果有@JsonManagedReference,则会自动注入@JsonBackReference标注的属性。

@JsonIgnore:直接忽略某个属性,以断开无限递归,序列化或反序列化均忽略。当然如果标注在get、set方法中,则可以分开控制,序列化对应的是get方法,反序列化对应的是set方法。在父子关系中,当反序列化时,@JsonIgnore不会自动注入被忽略的属性值(父或子),这是它跟@JsonBackReference和@JsonManagedReference最大的区别。

就是说,如果你只是向上面那样写,查询文章则不会包含用户信息,所以应该这么写:


    // user.java: 此注解避免Json解析时 post和author无限引用,忽略用户的文章
    @JsonBackReference
    public Set<Post> getPosts() {
        return posts;
    }

    // post.java: 此注解避免Json解析时 post和author无限引用,同时加载用户信息
    @JsonManagedReference
    public User getAuthor() {
        return author;
    }

我认为:查用户所有文章的时候肯定不是用的

    @JsonIgnore
    public User getAuthor() {
        return author;
    }

delete 操作不生效不报错

https://blog.csdn.net/u014074757/article/details/84625847

参照此篇文章作者的想法,问题应该是出现在已有的持久态对象持有该对象,检查我的代码,关联关系fetchType都是eager,改成lazy即可。

Repository 里写用@Query注解写原生SQL报错

添加 nativeQuery = true 属性

    @Query(value = "select name as name, count(id) as count from tag group by name order by count desc", nativeQuery = true)

但是这样就不能使用JPQL