在Spring-HibernateJava项目中替换类别的标记系统
有人知道如何设计类似于stackoverflow的标签系统吗 任何能够解释如何使用hibernate/spring实现这个系统的链接都会非常棒在Spring-HibernateJava项目中替换类别的标记系统,java,hibernate,spring,tags,categories,Java,Hibernate,Spring,Tags,Categories,有人知道如何设计类似于stackoverflow的标签系统吗 任何能够解释如何使用hibernate/spring实现这个系统的链接都会非常棒 我只是想找个起点 我建议从三个实体开始,一个用于被标记的对象(在SO示例中,这将是一个Post),一个用于保存标记定义(您可以称之为标记),另一个用于在这两个实体之间进行映射(称之为TaggedPost) 然后,将标记分配给帖子的基本过程如下: 查看具有给定名称的标记是否已存在,如果已存在,请使用现有标记,否则请插入新标记 创建一个新的TaggedPos
我只是想找个起点 我建议从三个
实体开始,一个用于被标记的对象(在SO示例中,这将是一个Post
),一个用于保存标记定义(您可以称之为标记
),另一个用于在这两个实体之间进行映射(称之为TaggedPost
)
然后,将标记
分配给帖子
的基本过程如下:
查看具有给定名称的标记是否已存在,如果已存在,请使用现有标记,否则请插入新标记
创建一个新的TaggedPost
实例,将Post
与步骤1中的Tag
链接起来
要从Post
中删除Tag
,只需删除相应的TaggedPost
实体即可
您可以使用Hibernate注释将应用于给定Post
的标记集作为Java集合公开,这样您就可以说getTags()
来获取所有标记。你可以在标记上做同样的事情,这样你就可以说getPosts()
来获取所有具有给定标记的帖子我建议从三个实体开始,一个用于被标记的对象(在so示例中,这将是一个Post
),一个用于保存您的标记定义(您可以将其称为标记
),另一个用于两者之间的映射(将其称为TaggedPost
)
然后,将标记
分配给帖子
的基本过程如下:
查看具有给定名称的标记是否已存在,如果已存在,请使用现有标记,否则请插入新标记
创建一个新的TaggedPost
实例,将Post
与步骤1中的Tag
链接起来
要从Post
中删除Tag
,只需删除相应的TaggedPost
实体即可
您可以使用Hibernate注释将应用于给定Post
的标记集作为Java集合公开,这样您就可以说getTags()
来获取所有标记。你可以在标签上做同样的事情,这样你就可以说getPosts()
来获得所有具有给定标签的帖子,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;
/* ... */
}
@实体
@表(name=“Tag”)
公共类标签{
@ManyToMany(fetch=FetchType.LAZY)
@可接合(
name=“PostTag”,
joinColumns=@JoinColumn(name=“TagId”),
inverseJoinColumns=@JoinColumn(name=“PostId”)
)
@外键(name=“FK_标签”,inverseName=“FK_标签”)
私人固定职位;
/* ... */
}
@实体
@表(name=“Post”)
公营职位{
@许多
@可接合(
name=“PostTag”,
joinColumns=@JoinColumn(name=“PostId”),
inverseJoinColumns=@JoinColumn(name=“TagId”)
)
@ForeignKey(name=“FK\u Post\u Tag”,inverseName=“FK\u Tag\u Post”)
@排序(comparator=CompareTagByName.class,type=SortType.comparator)
专用分类集标签;
/* ... */
}
优点是我们不需要手动维护连接。我们只需根据需要在每个Post
中添加或删除标记
另请注意:
- 在
Tag.posts
上懒抓取是个好主意。。。否则,每次显示标记时,您可能会导致Hibernate不必要地加载数千条Post
记录
- 通过提供带有
@sort
注释的比较器
,多对多连接使得按字母顺序对标记进行排序变得容易
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;
/* ... */
}
@实体
@表(name=“Tag”)
公共类标签{
@ManyToMany(fetch=FetchType.LAZY)
@可接合(
name=“PostTag”,
joinColumns=@JoinColumn(name=“TagId”),
inverseJoinColumns=@JoinColumn(name=“PostId”)
)
@外键(name=“FK_标签”,inverseName=“FK_标签”)
私人固定职位;
/* ... */
}
@实体
@表(name=“Post”)
公营职位{
@许多
@可接合(
name=“PostTag”,
joinColumns=@JoinColumn(name=“PostId”),
inverseJoinColumns=@JoinColumn(name=“TagId”)
)
@ForeignKey(name=“FK\u Post\u Tag”,inverseName=“FK\u Tag\u Post”)
@排序(comparator=CompareTagByName.class,type=SortType.comparator)
专用分类集标签;
/* ... */
}
优点是我们不需要手动维护连接。我们只需根据需要在每个Post
中添加或删除标记
另请注意:
- 在
Tag.posts
上懒抓取是个好主意。。。否则,每次显示标记时,您可能会导致Hibernate不必要地加载数千条Post
记录
- 通过提供带有
@sort
注释的比较器
,多对多连接使得按字母顺序对标记进行排序变得容易