Hibernate 多表联合查询 分页重复问题
今天进行在博客数据库分页查询了
里面表与表之间有的是一对一,有的是一对多关系
今天就是因为一对多关系中(文章和文章元数据,文章和tag信息的一对多关系),查询时出现了重复数据
请看如下dao层代码
public List<T> article(int page, int pagesize,int arcount) {
//获得分页数据
int fristint = (page==1?0:((page-1)*pagesize)); //获得开始数据 0 10 20 30
int endint = (arcount-((page-1)*pagesize)<pagesize?(arcount-((page-1)*pagesize)):pagesize); //获得当前页码的数据,1到10条
//创建DetachedCriteria对象
DetachedCriteria criteria = DetachedCriteria.forClass(Posts.class);
criteria.add(Restrictions.eq("postatus", "publish"));
criteria.add(Restrictions.eq("post_type", "post"));
criteria.addOrder(Order.desc("poid"));
@SuppressWarnings("unchecked")
List<T> list = (List<T>) hibernateTemplate.findByCriteria(criteria, fristint, endint);
return list;
我们再看看Posts里面的部分代码
private Set<Postmeta> postmeta = new HashSet<Postmeta>(0);
private Set<Term_relationships> term_relationships = new HashSet<Term_relationships>(0);
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "postid")
public Set<Postmeta> getPostmeta() {
return postmeta;
}
public void setPostmeta(Set<Postmeta> postmeta) {
this.postmeta = postmeta;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "objectid")
public Set<Term_relationships> getTerm_relationships() {
return term_relationships;
}
public void setTerm_relationships(Set<Term_relationships> term_relationships) {
this.term_relationships = term_relationships;
}
是的,实体Posts里面有两个集合。
当我们在dao层使用那样的代码进行查询,如果在实体Postmeta,和Term_relationships的字段postid和objectid有重复,那么你最后得到的分页数据就会出现重复
解决思路如下
第一步,在dao层增加如下代码
criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
此时查询的数据确实不会重复了,但是查询的数据却有问题了
比如我这里是查询的预期是16条数据。但是查询出来确是两条数据
其原因是因为在这个集合中有重复,两个关联表中就是一个表有三条重复,一个有五条重复,一共8条,然后Posts查询出2条,2*8就是16条
所以我们需要进行第二步
第二步,在dao层修改如下代码
DetachedCriteria criteria = DetachedCriteria.forClass(Posts.class);
为这样
DetachedCriteria criteria = DetachedCriteria.forClass(Posts.class).setFetchMode("postmeta", FetchMode.SELECT).setFetchMode("term_relationships", FetchMode.SELECT);
我们将postmeta和term_relationships设置为分别抓取,需要注意的时候,在OneToMany和ManyToOne中的加载方式需要设置为了急加载,即:
fetch = FetchType.EAGER)
此时,我们再次运行项目就会发现。已经正确的显示了分页数据
但是在控制台我们看见了有很多查询语句出现,估计应该多出有32次查询。这就说明问题已解决。
此时,Hibernate 多表联合查询 分页重复问题的得到解决!
爆款云服务器s6 2核4G 低至0.46/天,具体规则查看活动详情