hibernate 一对多关系查询出重复数据

SSH例子,一对多查询两张表,一级二级关系表,用了set集合,但查询出来会出现重复的数据。。。。望解答~~~

一级实体

public class subject01 {
    private int sub_id;
    private String sub_name;
    private String sub_introduce;
    private String sub_url;

    // 二级信息集合
    private Set<subject02> subject02Set = new HashSet<subject02>();
//set get ...
}

映射文件
图片描述

二级实体

public class subject02 {
    private int sub2_id;
    private String sub2_name;
    private int sub_id;
}

映射文件
图片描述

实现层

public class subject_sql_Implements {
    private SessionFactory sessionFactory;
    //    set get...
    // 一二级专题查询
    public List<subject01> selectOneAndTwo() {
        Session session = sessionFactory.openSession();
        List<subject01> list = new ArrayList<subject01>();
        //这个查询的结果是一个父级专题对应多个子级专题(用set集合)
        String Hql = "from subject01 s1  join s1.subject02Set";
        Query query = session.createQuery(Hql);
        // 这里将查询到结果集赋值给obj集合,而泛型为数组类型(subject02Set带有object数组),类似于二维数组
        List<Object[]> obj = query.list();
        for (int i = 0; i < obj.size(); i++) {
            // [0]获取第一个实体查询
            subject01 sub01 = (subject01) obj.get(i)[0];
            // (相同的只添加最后一个)
            if (i == obj.size() - 1) {
                list.add(sub01);
                break;
            }
            // 左边部分:获取父级主题的ID
            // 右边部分:obj集合里也获取到父级主题的ID
            // 左右两边进行匹配,排出重复项
            if (sub01.getSub_id() == ((subject01) obj.get(i + 1)[0]).getSub_id()) {
                continue;// 出现重复情况,继续循环
            } else {
                // 没有重复情况了,将数据添加进去
                list.add(sub01);
            }
        }
        return list;
    }
    //省略其他方法
}

数据库里对一级数据只存储了2条相关数据,但查询出来会有重复数据出现。
图片描述
图片描述

更新的代码

// 一二级专题查询
    public List<subject01> selectOneAndTwo() {
     Session session = sessionFactory.openSession();  
        String Hql = "from subject01 s1 left join fetch  s1.subject02Set";
        Query query = session.createQuery(Hql);       
        List<subject01> obj = query.list();
        //去掉了之前的去重的代码
        return obj;
    }

显示数据
图片描述

阅读 9.2k
5 个回答

修改如下:
String Hql = "from subject01 s1 left join fetch s1.subject02Set";
Query query = session.createQuery(Hql);
List<subject01> obj = query.list();
//如果需要拿到二级实体,obj.get(0).getSubject02Set(),就是这个一级实体下的二级实体。
看看可不可以?
为什么会重复出现:可以看看我以前学习hibernate 整理的一些文章,地址

其中有一个如下图片的位置重点看下。
20131107212755687
更新:
我看了下我以前的文章(上面地址给的文章中的“(2):迫切左外连接“这个章节),一对多的情况,使用String Hql = "from subject01 s1 left join fetch s1.subject02Set";语句还是会出现重复的,
查出来,使用hashset过滤一下subject01就可以了。hibernate我好久不用了。

//重写下equals和hashCode()方法
class subject01 {
    private int sub_id;
    private String sub_name;
    private String sub_introduce;
    private String sub_url;
    
    
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + sub_id;
        return result;
    }


    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        subject01 other = (subject01) obj;
        if (sub_id != other.sub_id)
            return false;
        return true;
    }


    // 二级信息集合
    private Set<subject02> subject02Set = new HashSet<subject02>();


    public int getSub_id() {
        return sub_id;
    }


    public void setSub_id(int sub_id) {
        this.sub_id = sub_id;
    }


    public String getSub_name() {
        return sub_name;
    }


    public void setSub_name(String sub_name) {
        this.sub_name = sub_name;
    }


    public String getSub_introduce() {
        return sub_introduce;
    }


    public void setSub_introduce(String sub_introduce) {
        this.sub_introduce = sub_introduce;
    }


    public String getSub_url() {
        return sub_url;
    }


    public void setSub_url(String sub_url) {
        this.sub_url = sub_url;
    }


    public Set<subject02> getSubject02Set() {
        return subject02Set;
    }


    public void setSubject02Set(Set<subject02> subject02Set) {
        this.subject02Set = subject02Set;
    }

//过滤多余的数据

String Hql = "from subject01 s1  left join fetch s1.subject02Set";
Query query = session.createQuery(Hql);
List<subject01> obj = query.list();
Set<subject01> set = new HashSet<subject01>(obj);  
obj = new ArrayList<subject01>(set);
//然后进行你自己下面的逻辑
  for (int i = 0; i < obj.size(); i++) {
    ..........
}

建议你去看看我上面的hibernate地址的相关文章。

先声明没用过HQL

 List<Object[]> obj = query.list(); 

本身是不是就重复;
hql解析完也是sql,sql你这俩张表inner join完毕之后也是5条记录,这不就是重复的吗;
2条记录inner join 5条 你自己inner join 一下 看是不是5条;
自己写个inner join试一下啊


应邀过来强答,反而被踹一脚,我发现,很多人都是不爱点赞,特别爱踩人

写一下答案,讲真我昨天晚上看例子代码的时候啥都没改,今儿早上想继续写项目发现出这么个BUG,,,排查一天。。。。扎心。。

subject01

package Entity;
public class subject01 {
    private int sub_id;
    private String sub_name;
    private String sub_introduce;
    private String sub_url;

    // 二级信息集合
    private Set<subject02> subject02Set = new HashSet<subject02>();

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + sub_id;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        subject01 other = (subject01) obj;
        if (sub_id != other.sub_id)
            return false;
        return true;
    }

    //set get
}

业务实现代码

// 一二级专题查询
    public List<cms_subject01> selectOneAndTwo() {
        Session session = sessionFactory.openSession();
        String Hql = "from cms_subject01 s1 left join fetch s1.subject02Set";
        Query query = session.createQuery(Hql);
        List<cms_subject01> obj = query.list();
        Set<cms_subject01> set = new HashSet<cms_subject01>(obj);
        obj = new ArrayList<cms_subject01>(set);
        return obj;
    }

图片描述

我没看你的代码,如果我碰到这个逻辑我会用leftjoin 啊

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题