[英]Mapping one-to-many with no duplicates
我正在嘗試做我認為在Jpa Spring JPA(休眠)中的“一對多”關系,其中我有三個表(Post,Tag,Post_tag)。
一個帖子可能有多個標簽,多個帖子可能會共享相同的標簽以及其他標簽。 標簽重疊的地方,標簽表中應該只有該標簽的一個實例。
該結構類似於以下內容:
發布:
Post_tag:
標簽:
我的理解是,從郵政的角度來看,這是“一對多”的關系,而從“標簽”角度來看,這是“一對多”的關系。 目前,我已經設法使用多對一關系來完成這項工作,但是,這會產生許多具有不同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.