2011-03-22 17 views

回答

1

我建議開始有三個Entities,一個正在被標記的對象(在SO例子的情況下,這將是一個Post),一個牽着你的標籤定義(你可以調用這個Tag ),以及兩者之間的映射(稱爲這一個TaggedPost)。

然後分配的基本過程TagPost雲一樣的東西:

  1. 看看是否與給定名稱的Tag已經存在,如果是,利用現有的一個,否則插入一個新的。
  2. 創建一個新的TaggedPost實例從步驟1

鏈接PostTag要從Post你只是刪除相應的TaggedPost實體刪除Tag

您可以使用Hibernate註釋將適用於給定Post的標記集作爲Java集合公開,以便您可以僅說getTags()即可獲取所有標記。並且您可以在Tag上做同樣的事情,以便您可以說getPosts()以獲得具有給定Tag的所有帖子。

1

aroth對三個實體的回答是完全有效的,但我們僅使用兩個實體做同樣的事情,因爲第三個實體(即TaggedPost)不會爲我們增加任何價值。

我們的實體是這個樣子:

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

    @ManyToMany(fetch=FetchType.LAZY) 
    @JoinTable(
      name="PostTag", 
      [email protected](name="TagId"), 
      [email protected](name="PostId") 
    ) 
    @ForeignKey(name="FK_Tag_Post", inverseName="FK_Post_Tag") 
    private Set<Post> posts; 

    /* ... */ 

} 


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

    @ManyToMany 
    @JoinTable(
      name="PostTag", 
      [email protected](name="PostId"), 
      [email protected](name="TagId") 
    ) 
    @ForeignKey(name="FK_Post_Tag", inverseName="FK_Tag_Post") 
    @Sort(comparator=CompareTagByName.class, type=SortType.COMPARATOR) 
    private SortedSet<Tag> tags; 

    /* ... */ 

} 

的優點是,我們不需要手動維護加盟。我們只需根據需要從每個Post中添加或刪除Tag

還要注意:

  • 延遲抓取上Tag.posts是個好主意......否則你可能會休眠不必要加載的Post數千每次顯示一個標記時間的記錄。
  • 許多一對多的加入可以很容易地按照字母順序排序的標籤,通過提供Comparator@Sort註釋