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/天,具体规则查看活动详情