【发布时间】:2011-03-22 23:38:54
【问题描述】:
有谁知道如何在 stackoverflow 设计类似于此处使用的标签系统?
任何可以解释如何使用 hibernate/spring 实现这个系统的链接都很棒。
我只是在寻找一些起点。
【问题讨论】:
标签: java hibernate spring tags categories
有谁知道如何在 stackoverflow 设计类似于此处使用的标签系统?
任何可以解释如何使用 hibernate/spring 实现这个系统的链接都很棒。
我只是在寻找一些起点。
【问题讨论】:
标签: java hibernate spring tags categories
aroth 对三个实体的回答完全有效,但我们只使用两个实体做同样的事情,因为第三个实体(即TaggedPost)不会为我们增加任何价值。
我们的实体看起来像这样:
@Entity
@Table(name = "Tag")
public class Tag {
@ManyToMany(fetch=FetchType.LAZY)
@JoinTable(
name="PostTag",
joinColumns=@JoinColumn(name="TagId"),
inverseJoinColumns=@JoinColumn(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",
joinColumns=@JoinColumn(name="PostId"),
inverseJoinColumns=@JoinColumn(name="TagId")
)
@ForeignKey(name="FK_Post_Tag", inverseName="FK_Tag_Post")
@Sort(comparator=CompareTagByName.class, type=SortType.COMPARATOR)
private SortedSet<Tag> tags;
/* ... */
}
优点是我们不需要手动维护join。我们只需根据需要从每个Post 添加或删除Tag。
另请注意:
Tag.posts 上延迟获取是个好主意...否则您可能会导致 Hibernate 在每次显示标签时不必要地加载数千条 Post 记录。@Sort 注释的Comparator,多对多连接可以轻松按字母顺序对标签进行排序【讨论】:
我建议从三个Entities 开始,一个用于被标记的对象(在 SO 示例的情况下,这将是一个Post),一个用于保存您的标记定义(您可以只称之为Tag),一个用于两者之间的映射(称之为TaggedPost)。
然后将Tag 分配给Post 的基本过程如下:
Tag 是否已存在,如果存在,则使用现有的,否则插入新的。TaggedPost 实例,将Post 与步骤1 中的Tag 链接起来。要从Post 中删除Tag,您只需删除相应的TaggedPost 实体即可。
您可以使用 Hibernate 注释将应用于给定 Post 的标签集公开为 Java 集合,以便您只需说出 getTags() 即可获取所有标签。你可以在Tag 上做同样的事情,这样你就可以说getPosts() 来获取所有具有给定Tag 的帖子。
【讨论】: