hql语句:一对多查询

一对多的查询又包含以下情况:
1、等值连接
2、内连接
3、迫切内连接
4、左外连接
5、迫切左外连接

1、等值连接:一对多查询的时候,由于使用的hql语句,是根据类来查询的,所以hql语句这样表示:

    /**
     * 等值连接
     */
    public void Connect_equal(){
        Session session=sessionFactory.openSession();
        //因为hql语句,是根据pojo类来查询的,所以这里要用到类名
        //又因为Student没有cid属性,但是有classes属性,所以通过classes获得cid
        String hql="from Classes c,Student s where c.cid=s.classes.cid";
        List<Classes> classes=session.createQuery(hql).list();
        session.close();
    }

运行之后的List集合的结构:
这里写图片描述
在单表查询中,我们说过。结构为数组的形式不好遍历

那我们就来试一下内连接:

/**
     * 内连接
     */
    public void Connect_inner(){
        Session session=sessionFactory.openSession();
        String hql="from Classes c inner join Student s on(c.cid=s.classes.cid)";
        List<Classes> classes=session.createQuery(hql).list();
        session.close();
    }

我们根据sql的基础,理所当然的使用了上面的查询语句,可是运行之后报错了,
可是执行如下语句的时候,通过了

public void Connect_ineer2(){
        Session session=sessionFactory.openSession();
        //在使用hql语句的时候,要处处想着我们使用的是类,而不是表!!
        String hql="from Classes c inner join c.students";
        List<Classes> classes=session.createQuery(hql).list();
        session.close();
    }

运行之后,集合的结构为:
这里写图片描述
虽然说等值连接跟内连接的效果是一样的,但是它们的产生的集合结构也是一样的。

由于这种结构的不完善,所以就出现了迫切内连接:

public void fetch_inner(){
        Session session=sessionFactory.openSession();
        String hql="from Classes c inner join fetch c.students";
        List<Classes> classes=session.createQuery(hql).list();
        session.close();
    }

迫切内连接,只需要在内连接的join后面 加上fetch 即可
运行之后的 结果为:
这里写图片描述
这时,list集合里面的内容为对象,而不是数组

有时候根据需求,我们要查询所有的数据,所以我们要用到左连接

/**
左外连接
*/
public void Connect_leftJoin(){
        Session session=sessionFactory.openSession();
        String hql="from Classes c left join  c.students";
        List<Classes> classes=session.createQuery(hql).list();
        session.close();
    }

运行之后的集合结构为:
这里写图片描述
,经过上面几种连接, 我们可以发现,都是迫切连接,才能解决结构为数组的问题,所以我们用迫切左外连接来做一下

  /**
    * 迫切左外连接
    */
    public void Connect_fetch_join(){
        Session session=sessionFactory.openSession();
        String hql="from Classes c left join fetch c.students";
        List<Classes> classes=session.createQuery(hql).list();
        session.close();
    }

运行之后,list的结构为:
这里写图片描述

另外,如果我们需要的数据,与表中的字段数相差太多,我们可以自己建立一个javaBean,然后把我们自己需要的数据定义在javaBean里面,并且把带参和空参的构造函数创建好。然后我们就可以使用new的方法来进行连接查询:

    /**
     * 带select的左外连接查询
     */
    public void Select_join2(){
        Session session=sessionFactory.openSession();
        String hql="select new cn.ansel.domain.ClassView(c.cname,s.sname) from Student s left join  s.classes c";
        List<Classes> classes=session.createQuery(hql).list();
        session.close();
    }

运行之后:这里写图片描述

细心的可以发现,上面带select的语句,我既没有用

select new cn.ansel.domain.ClassView(c.cname,c.students.sname) from Classes c left join fetch c.students

又没有用这样

select new cn.ansel.domain.ClassView(c.cname,c.students.sname) from Classes c left join  c.students

的语句进行查询,因为第一句,new构造函数的方法,不适合于fecth一起使用,二者选一,又因为第二种的c.students.sname属性为多的一方,在这里只是获取属性,而不是遍历,不知道指向哪个对象。所以我们要用Student放在前面,因为student与classes是多对一的关系,所以我们当前的student都能获到唯一的classes,所以使用student在前面。

下面我们来说说new构造函数这种方法的弊端:
由于一般的项目,我们都是通过用户在页面输入数据,然后把数据传送到action中,这时候接受数据的比如是Classes类,然后由于我们只需要用户输入数据的一两种(比用户输入的字段数量少得多的情况下),所以我们要另外创建一个javaBean,把我们需要在页面上显示的数据定义为该javaBean的属性,然后设置好getter&setter以及带参&空参构造函数之后,我们调用service和dao来保存这个用户,由于我们自己创建的javaBean与用户输入的Classes不一样,所以我们要在Dao操作之前,要对javaBean进行处理。这个处理可能简单,也可能很麻烦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值