HQL多表查询 ---- Hibernate之查询语句
叙:上一章节轻风记录的是HQL的单表查询,本章节就HQL的多表查询方式进行记录;
HQL查询数据
本章节主要学习的是HQL查询方式的表查询;
几种查询方式
1. 内连查询
查询语句比较奇怪,from Customer c inner join c.linkMens,查询Customer类所映射的表和Customer类中linkMens属性所代表的实体类的映射的数据库表;这句话很拗口,但是多读两遍理解理解就好了,重点理解的是linkMens是Customer类中的属性,linkMens是LinkMan实体类在Customer类中的对象属性,因此,在内连查询中也可以理解为,查询两张表中的数据,对一个类进行操作,但是这个类中必须含有另一个表的映射类的对象属性才行。具体的代码如下所示:
查询代码:
@Test // HQL的内连接 public void demo1() { Session session = HibernateUtils.openSession(); Transaction bt = session.beginTransaction(); String hql = " from Customer c inner join c.linkMens "; Query query = session.createQuery(hql); List<Object[]> list = query.list(); for (Object[] arr : list) { System.out.println(Arrays.toString(arr)); } bt.commit(); session.close(); }
要知道的是,既然是多表查询的内连查询,那么就应该考虑到之前学过的关联映射的知识,内连查询就是指查询类A中的一条数据a所关联的类B中的所有数据,因此可以视为(就是)“一对多”关系,因此,在类A的实体类中要有关联类B的对象集合;
在Customer类中的代码:
运行Demo后的结果:
从查询代码和查询结果中看得出,查询获得的数据是集合数组,因为内连查询获得的是以键值对的形式显示出来的,“键”是Customer类所映射的表中的数据,“值”是linkMens所代表的实体类所映射的数据表的数据;因此需要使用Object[]的范型进行约束;
2. 迫切查询
迫切查询,主要有两点和内连查询不同,第一点是,在查询语句中添加一个关键字,第二点是,由于查询语句变化导致的,导致查询到的结果显示形式不同,内连查询获得的数据是键值对的形式,而迫切查询获得的是合并后的数据形式,将两条数据合为一条新的并以主查询实体类的数据形式返回;
查询代码如下:
@Test // HQL迫切查询 public void demo2() { Session session = HibernateUtils.openSession(); Transaction bt = session.beginTransaction(); String hql = " from Customer c inner join fetch c.linkMens "; Query query = session.createQuery(hql); List<Customer> list = query.list(); System.out.println(list); bt.commit(); session.close(); }
添加的关键字:fetch
这个例子中主查询类是Customer,所以其返回值的范型是Customer,运行的结果如下图所示:
从中可以看出,数据变成了一条一条的被放在以一个数据集合中;
3. 左外连接查询
首先左连接的特点是查询出来的结果,左边不能为空,右边可以为空,右连接与此相反;
在进行demo代码编写时先在两个表中分别加入一条没有关联的数据,既是LinkMan表中加入一条lkm_cust_id列为空的数据,在Customer表中加入一条只有cust_name数据的数据;
下边是demo的编写,和内连接只多一个关键字left;
@Test // HQL的左连接查询 public void demo3() { Session session = HibernateUtils.openSession(); Transaction bt = session.beginTransaction(); String hql = " from Customer c left join c.linkMens "; Query query = session.createQuery(hql); List<Object[]> list = query.list(); for (Object[] arr : list) { System.out.println(Arrays.toString(arr)); } bt.commit(); session.close(); }
查询到的结果如下:
4. 右外连接查询
和左外连接查询基本一样,只不过关键字和查询可为空、不可为空的像颠倒了;
代码:
@Test // HQL的右连接查询 public void demo4() { Session session = HibernateUtils.openSession(); Transaction bt = session.beginTransaction(); String hql = " from Customer c right join c.linkMens "; Query query = session.createQuery(hql); List<Object[]> list = query.list(); for (Object[] arr : list) { System.out.println(Arrays.toString(arr)); } bt.commit(); session.close(); }
查询到的结果如下:
pass:一般情况下多表查询不会用HQL来进行,因为语法比较拗口(拗脑子),如果多表查询的话查询的表太多了就会导致语法混乱不易修改维护等;
pass~pass:下一章节记录QBC数据查询方式~