簡體   English   中英

一對多映射,無重復

[英]Mapping one-to-many with no duplicates

我正在嘗試做我認為在Jpa Spring JPA(休眠)中的“一對多”關系,其中我有三個表(Post,Tag,Post_tag)。

一個帖子可能有多個標簽,多個帖子可能會共享相同的標簽以及其他標簽。 標簽重疊的地方,標簽表中應該只有該標簽的一個實例。

該結構類似於以下內容:

發布:

  • ID
  • 名稱

Post_tag:

  • post_id
  • tag_id

標簽:

  • ID
  • 標簽

我的理解是,從郵政的角度來看,這是“一對多”的關系,而從“標簽”角度來看,這是“一對多”的關系。 目前,我已經設法使用多對一關系來完成這項工作,但是,這會產生許多具有不同ID的相同標簽,並且會使數據庫混亂,從而使其減慢速度,並使我產生緩存結果,從而導致Redis嘗試加快查詢速度這是一個臨時解決方案!

我目前擁有的是:

@Table(name="Post")
public class Post implements Serializable {

...

@ManyToOne(targetEntity = Tags.class, cascade = {CascadeType.ALL, CascadeType.MERGE})
@JoinTable(name = "post_tags",
            joinColumns = {@JoinColumn(name = "post_id")},
            inverseJoinColumns = {@JoinColumn(name = "tag_id", unique=true)})
@OneToMany(fetch=FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="post_tags")
    public Set<Tags> tags;

和標簽表:

@Column(name = "tag", unique = true)
private String tag;

謝謝!

您的scnerio實際上是多對多的關系。 您最好使用@ManyToMany 像下面這樣。

@Entity
@Table(name = "Tag")

public class Tag{ 
    @ManyToMany(cascade = { CascadeType.ALL })
    @JoinTable(
        name = "Post_Tag", 
        joinColumns = { @JoinColumn(name = "tag_id") }, 
        inverseJoinColumns = { @JoinColumn(name = "post_id") }
    )
    Set<Post> posts = new HashSet<>();

    // standard constructor/getters/setters
}

@Entity
@Table(name = "Post")
public class Post{    


    @ManyToMany(mappedBy = "posts")

    private Set<Tag> tags= new HashSet<>();

    // standard constructors/getters/setters   
}

問題是您的帖子引用了您的標簽表。 應該是您的帖子,引用您的Post_Tag表以獲取標簽:

@Entity
@Table(name = "post")
public class Post implements Serializable {

  private static final long serialVersionUID = 1L;
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Basic(optional = false)
  @Column(name = "id")
  private Integer id;
  @Column(name = "post")
  private String post;
  @OneToMany(cascade = CascadeType.ALL, mappedBy = "postId")
  private List<PostTag> postTagList;
}

@Entity
@Table(name = "tag")
public class Tag implements Serializable {

  private static final long serialVersionUID = 1L;
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Basic(optional = false)
  @Column(name = "id")
  private Integer id;
  @Column(name = "tag")
  private String tag;
  @OneToMany(cascade = CascadeType.ALL, mappedBy = "tagId")
  private List<PostTag> postTagList;
}


@Entity
@Table(name = "post_tag")
public class PostTag implements Serializable {

  private static final long serialVersionUID = 1L;
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Basic(optional = false)
  @Column(name = "id")
  private Integer id;
  @JoinColumn(name = "post_id", referencedColumnName = "id")
  @ManyToOne(optional = false)
  private Post postId;
  @JoinColumn(name = "tag_id", referencedColumnName = "id")
  @ManyToOne(optional = false)
  private Tag tagId;
}

上面有單獨的post和tag實體,以及同時引用這兩個實體的PostTag實體。

現在,您可以在for循環中調用post.getPostTagList()以獲取帖子的所有標簽,例如:

for (PostTag postTag : post.getPostTagList()) {
  Tag tag = postTag.getTag();
  String tagValue = tag.getTag();
}

需要注意的一件事是,默認情況下,休眠會延遲進行懶惰獲取,因此列表可能會出錯。 您將必須編寫查詢才能從存儲庫中快速獲取數據,或者您卻獲取數據

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM