hql语句:一对多查询
2015-09-07 10:57
405 查看
一对多的查询又包含以下情况:
1、等值连接
2、内连接
3、迫切内连接
4、左外连接
5、迫切左外连接
1、等值连接:一对多查询的时候,由于使用的hql语句,是根据类来查询的,所以hql语句这样表示:
运行之后的List集合的结构:
![](https://img-blog.csdn.net/20150907095528035)
在单表查询中,我们说过。结构为数组的形式不好遍历
那我们就来试一下内连接:
我们根据sql的基础,理所当然的使用了上面的查询语句,可是运行之后报错了,
可是执行如下语句的时候,通过了
运行之后,集合的结构为:
![](https://img-blog.csdn.net/20150907101254685)
虽然说等值连接跟内连接的效果是一样的,但是它们的产生的集合结构也是一样的。
由于这种结构的不完善,所以就出现了迫切内连接:
迫切内连接,只需要在内连接的join后面 加上fetch 即可
运行之后的 结果为:
![](https://img-blog.csdn.net/20150907101758603)
这时,list集合里面的内容为对象,而不是数组
有时候根据需求,我们要查询所有的数据,所以我们要用到左连接
运行之后的集合结构为:
![](https://img-blog.csdn.net/20150907102545906)
,经过上面几种连接, 我们可以发现,都是迫切连接,才能解决结构为数组的问题,所以我们用迫切左外连接来做一下
运行之后,list的结构为:
![](https://img-blog.csdn.net/20150907102927136)
另外,如果我们需要的数据,与表中的字段数相差太多,我们可以自己建立一个javaBean,然后把我们自己需要的数据定义在javaBean里面,并且把带参和空参的构造函数创建好。然后我们就可以使用new的方法来进行连接查询:
运行之后:
![](https://img-blog.csdn.net/20150907104734485)
细心的可以发现,上面带select的语句,我既没有用
又没有用这样
的语句进行查询,因为第一句,new构造函数的方法,不适合于fecth一起使用,二者选一,又因为第二种的c.students.sname属性为多的一方,在这里只是获取属性,而不是遍历,不知道指向哪个对象。所以我们要用Student放在前面,因为student与classes是多对一的关系,所以我们当前的student都能获到唯一的classes,所以使用student在前面。
下面我们来说说new构造函数这种方法的弊端:
由于一般的项目,我们都是通过用户在页面输入数据,然后把数据传送到action中,这时候接受数据的比如是Classes类,然后由于我们只需要用户输入数据的一两种(比用户输入的字段数量少得多的情况下),所以我们要另外创建一个javaBean,把我们需要在页面上显示的数据定义为该javaBean的属性,然后设置好getter&setter以及带参&空参构造函数之后,我们调用service和dao来保存这个用户,由于我们自己创建的javaBean与用户输入的Classes不一样,所以我们要在Dao操作之前,要对javaBean进行处理。这个处理可能简单,也可能很麻烦
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进行处理。这个处理可能简单,也可能很麻烦
相关文章推荐
- kindeditor 批量上传 上传失败 thinkphp swfupload session
- 杰奇登录后的东西都是在session里面的
- ASP中SESSION无法保存问题的解决办法
- sql2008 hql语句翻译过来的分页语句介绍
- Oracle中的Connect/session和process的区别及关系介绍
- Node.js编程中客户端Session的使用详解
- 浅谈COOKIE和SESSION区别
- 解析PHP的session过期设置
- php中Session的生成机制、回收机制和存储机制探究
- php中将一个对象保存到Session中的方法
- 深入解析Session是否必须依赖Cookie
- PHP Session机制简介及用法
- 新手菜鸟必读:session与cookie的区别
- 深入讲解PHP Session及如何保持其不过期的方法
- PHP Session变量不能传送到下一页的解决方法
- PHP中的session永不过期的解决思路及实现方法分享
- *.ashx文件不能访问Session值的解决方法
- ASP.NET中Session和Cache的区别总结
- ASP.NET中在不同的子域中共享Session的具体方法