##Hibernate框架学习之查询 ##
----------
例一:使用hibernate完成所有的员工的查询
----
**需求分析**
1.完成所有员工的查询
2.准备数据
public class Emp {
private Integer e_id;
private String e_name;
private String e_address;
private String e_phone;
private Dept dept;
public Emp(){
}
public Emp(String e_name,String e_address){
this.e_name=e_name;
this.e_address=e_address;
}
@Override
public String toString() {
return "Emp [e_id=" + e_id + ", e_name=" + e_name + ", e_address=" + e_address + ", e_phone=" + e_phone
+ "]";
}
:
:
}
public class Dept {
private Integer d_id;
private String d_name;
private Set<Emp> emps=new HashSet<Emp>();
@Override
public String toString() {
return "Dept [d_id=" + d_id + ", d_name=" + d_name + ", emps=" + emps + "]";
}
:
:
}
使用hibernate插入数据
@Test
public void test1(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
//插入数据测试
Dept dept1 = new Dept();
Dept dept2 = new Dept();
Dept dept3 = new Dept();
Dept dept4 = new Dept();
dept1.setD_name("研发部");
dept2.setD_name("测试部");
dept3.setD_name("运维部");
dept4.setD_name("销售部");
Emp emp1 = new Emp();
Emp emp2 = new Emp();
Emp emp3 = new Emp();
Emp emp4 = new Emp();
Emp emp6 = new Emp();
emp1.setE_address("湖南");
emp1.setE_name("小王");
emp1.setDept(dept1);
emp4.setE_address("广东");
emp4.setE_name("小张");
emp4.setDept(dept1);
emp2.setE_address("湖北");
emp2.setE_name("小李");
emp2.setDept(dept2);
emp3.setE_address("广东");
emp3.setE_name("小邓");
emp3.setDept(dept3);
emp6.setE_address("广东");
emp6.setE_name("小胡");
session.save(emp1);
session.save(emp2);
session.save(emp3);
session.save(emp4);
session.save(emp6);
session.save(dept4);
tr.commit();
session.close();
}
-----
**hibernate插件的查询方式有下面几种**
1.唯一标识OID的检索方式
//session.get(对象.class,OID);
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Emp emp = session.get(Emp.class, 1);
System.out.println(emp.getDept().getD_name());
tr.commit();
session.close();
查询结果:研发部
2.对象导航的检索方式
/**
* 对象导航的方式
*/
@Test
public void test3(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Dept dept = session.get(Dept.class, 1);
System.out.println(dept.getEmps().size());
tr.commit();
session.close();
}
输出结果:2
值得注意的是,在这里我们借助了OID的方式获得了部门对象,并没有得到员工对象,但是我们依然打印出了该部门下员工的人数
3.HQL的检索方式
HQL全称为:Hibernate Query Language 是hibernate框架自己的查询体系
4.QBC的检索方式
QBC全称为:Query By Criteria //通过criteria接口的条件查询
5.原始SQL检索
hibernate支持原始SQL语句的查询,但是这与Hibernate的ORM思想不一致!
-------
**下面详细介绍下HQL检索与QBC检索**
-----
**HQL查询**
1.HQL查询概述:
HQL查询是一种面向对象的查询方式,符合ORM思想,底层采用映射的方式将HQL语句转为相应的SQL语句.
2.与SQL语句的区别与联系
底层依然是SQL语句,SQL操作的对象是字段和表,而HQL基于ORM思想操作的属性和对象
3.查询语句演示
3.1 基本查询格式
@Test
public void test4(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
List<Emp> list = session.createQuery("from Emp").list();
for (Emp emp : list) {
System.out.print(emp.getE_name()+",");
}
tr.commit();
session.close();
}
查询结果:小王,小李,小邓,小张,小胡,
注意,这里使用的是类名
3.2 HQL查询支持别名的方式
List<Emp> list = session.createQuery("select e from Emp e").list();
3.3 HQL排序查询
List<Emp> list = session.createQuery("from Emp order by e_id desc").list();
List<Emp> list = session.createQuery("from Emp order by e_id asc").list();
3.4 HQL分页查询
Query query = session.createQuery("from Emp");
//得到Qeury对象,设置开始页
query.setFirstResult(0);
//设置每一页显示条数
query.setMaxResults(3);
List<Emp> list = query.list();
for (Emp emp : list) {
System.out.println(emp);
}
结果:
Emp [e_id=1, e_name=小王, e_address=湖南, e_phone=null]
Emp [e_id=2, e_name=小李, e_address=湖北, e_phone=null]
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]
3.5 HQL按条件查询
Query query = session.createQuery("from Emp where e_name like ?");
query.setParameter(0, "%王%");
List<Emp> list = query.list();
for (Emp emp : list) {
System.out.println(emp);
}
结果是:Emp [e_id=1, e_name=小王, e_address=湖南, e_phone=null]
注意,此时占位符是从0开始的
3.6 HQL投影查询(其实就是选择几个想要的字段,无关字段不显示信息)
与 SELECT e_name,e_address FROM e_emp;的效果是一致的
@Test
public void test9(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Query query = session.createQuery("select e.e_name,e.e_address from Emp e");
List<Emp> list = query.list();
for (Emp emp : list) {
System.out.println(emp);
}
tr.commit();
session.close();
}
这样写会报错,因为返回的是一个Object类型的数组:java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to top.lingzhen.domain.Emp
HIbernate给我们提供另外的方式即使是单个字段仍然可以封装为对象,但是需要提供必要的构造方法,并且无参构造方法仍需保留
@Test
public void test10(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Query query = session.createQuery("select new Emp(e.e_name,e.e_address) from Emp e");
List<Emp> list = query.list();
for (Emp emp : list) {
System.out.println(emp.getE_name()+emp.getE_address());
}
tr.commit();
session.close();
}
此时Emp实体类变化为
public class Emp {
private Integer e_id;
private String e_name;
private String e_address;
private String e_phone;
private Dept dept;
public Emp(){
}
public Emp(String e_name,String e_address){
this.e_name=e_name;
this.e_address=e_address;
}
:
:
}
3.7 HQL查询之聚合函数查询
Query query = session.createQuery("select count(*) from Emp");
List<Number> list = query.list();
System.out.println(list.get(0).intValue());
注意:此时返回的泛型类型,其他聚合函数查询与上面类似
---
**QBC**查询
1.Queyr By Criteria查询是一种完全面向对象的查询
2.QBC的简单格式
List<Emp> list = session.createCriteria(Emp.class).list();
for (Emp emp : list) {
System.out.println(emp);
}
输出结果是
Emp [e_id=1, e_name=小王, e_address=湖南, e_phone=null]
Emp [e_id=2, e_name=小李, e_address=湖北, e_phone=null]
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]
Emp [e_id=4, e_name=小张, e_address=广东, e_phone=null]
Emp [e_id=5, e_name=小胡, e_address=广东, e_phone=null]
3.QBC的排序查询
@Test
public void test2(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Criteria criteria = session.createCriteria(Emp.class);
List<Emp> list = criteria.addOrder(Order.desc("e_id")).list();
for (Emp emp : list) {
System.out.println(emp);
}
}
Emp [e_id=5, e_name=小胡, e_address=广东, e_phone=null]
Emp [e_id=4, e_name=小张, e_address=广东, e_phone=null]
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]
Emp [e_id=2, e_name=小李, e_address=湖北, e_phone=null]
Emp [e_id=1, e_name=小王, e_address=湖南, e_phone=null]
QBC查询都是通过调用方法实现查询的,查询条件就是对应的类属性
4.QBC的分页查询
@Test
public void test3(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Criteria criteria = session.createCriteria(Emp.class);
criteria.setFirstResult(0);
criteria.setMaxResults(3);
List<Emp> list = criteria.list();
for (Emp emp : list) {
System.out.println(emp);
}
}
输出结果:
Emp [e_id=1, e_name=小王, e_address=湖南, e_phone=null]
Emp [e_id=2, e_name=小李, e_address=湖北, e_phone=null]
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]
5.QBC的条件查询
@Test
public void test4(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Criteria criteria = session.createCriteria(Emp.class);
criteria.addOrder(Order.desc("e_id"));
criteria.add(Restrictions.ge("e_id", 2));
List<Emp> list = criteria.list();
for (Emp emp : list) {
System.out.println(emp);
}
}
输出结果:
Emp [e_id=5, e_name=小胡, e_address=广东, e_phone=null]
Emp [e_id=4, e_name=小张, e_address=广东, e_phone=null]
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]
Emp [e_id=2, e_name=小李, e_address=湖北, e_phone=null]
如果想查询多个条件,可以使用Restrictions.or(Restrictions.XX(),Restrictions.XX()...)或者Restrictions.add(...)
Restrictions.eq //相等
Restrictions.gt // 大于号
Restrictions.ge // 大于等于
Restrictions.lt // 小于
Restrictions.le // 小于等于
Restrictions.between // 在之间
Restrictions.like // 模糊查询
Restrictions.in // 范围
Restrictions.and // 并且
Restrictions.or // 或者
6.QBC的聚合函数查询
需要借助Projection来进行查询
@Test
public void test5(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Criteria criteria = session.createCriteria(Emp.class);
List<Number> list = criteria.setProjection(Projections.rowCount()).list();
System.out.println(list.get(0).intValue());
/*criteria.setProjection(null);//如果要执行注释部分的代码,需要执行这句,破坏其格式
List<Emp> list2 = criteria.addOrder(Order.desc("e_id")).list();
for (Emp emp : list2) {
System.out.println(emp);
}*/
}
----
**离线条件查询**
1.离线条件查询的意义:可以在WEB层不借助session获得查询对象,进行查询条件的拼接,最后执行把离线查询对象传到持久层就可以了,简化开发,不过在执行的适合还是需要session对象。
@Test
public void test6(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
DetachedCriteria forClass = DetachedCriteria.forClass(Emp.class);
DetachedCriteria add = forClass.add(Restrictions.ge("e_id",3));
//执行时仍需要session
List<Emp> list = add.getExecutableCriteria(session).list();
for (Emp emp : list) {
System.out.println(emp);
}
}
执行结果:
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]
Emp [e_id=4, e_name=小张, e_address=广东, e_phone=null]
Emp [e_id=5, e_name=小胡, e_address=广东, e_phone=null]
-----
**HQL的多表查询**
1.普通内连接
@Test
public void test6(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
//注意返回结果
List<Object[]> list=session.createQuery("from Emp e inner join e.dept").list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
}
2.使用fetch关键字的迫切内连接,能将查询结果封装为对象
@Test
public void test7(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
List<Emp> list=session.createQuery("from Emp e inner join fetch e.dept").list();
for (Emp emp : list) {
System.out.println(emp+"=="+emp.getDept().getD_name());
}
}
查询结果:
Emp [e_id=1, e_name=小王, e_address=湖南, e_phone=null]==研发部
Emp [e_id=4, e_name=小张, e_address=广东, e_phone=null]==研发部
Emp [e_id=2, e_name=小李, e_address=湖北, e_phone=null]==测试部
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]==运维部
3.左外连接,右外连接查询与上面相似
left join fetch //迫切左外连接
right join fetch //迫切右外连接
@Test
public void test8(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
List<Emp> list=session.createQuery("from Emp e left join fetch e.dept").list();
for (Emp emp : list) {
System.out.println(emp);
}
}
查询结果:
Emp [e_id=1, e_name=小王, e_address=湖南, e_phone=null]
Emp [e_id=2, e_name=小李, e_address=湖北, e_phone=null]
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]
Emp [e_id=4, e_name=小张, e_address=广东, e_phone=null]
Emp [e_id=5, e_name=小胡, e_address=广东, e_phone=null]
注意,不同的左右表查询最后的结果是不一致的,封装不上就为null
---
----------
例一:使用hibernate完成所有的员工的查询
----
**需求分析**
1.完成所有员工的查询
2.准备数据
public class Emp {
private Integer e_id;
private String e_name;
private String e_address;
private String e_phone;
private Dept dept;
public Emp(){
}
public Emp(String e_name,String e_address){
this.e_name=e_name;
this.e_address=e_address;
}
@Override
public String toString() {
return "Emp [e_id=" + e_id + ", e_name=" + e_name + ", e_address=" + e_address + ", e_phone=" + e_phone
+ "]";
}
:
:
}
public class Dept {
private Integer d_id;
private String d_name;
private Set<Emp> emps=new HashSet<Emp>();
@Override
public String toString() {
return "Dept [d_id=" + d_id + ", d_name=" + d_name + ", emps=" + emps + "]";
}
:
:
}
使用hibernate插入数据
@Test
public void test1(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
//插入数据测试
Dept dept1 = new Dept();
Dept dept2 = new Dept();
Dept dept3 = new Dept();
Dept dept4 = new Dept();
dept1.setD_name("研发部");
dept2.setD_name("测试部");
dept3.setD_name("运维部");
dept4.setD_name("销售部");
Emp emp1 = new Emp();
Emp emp2 = new Emp();
Emp emp3 = new Emp();
Emp emp4 = new Emp();
Emp emp6 = new Emp();
emp1.setE_address("湖南");
emp1.setE_name("小王");
emp1.setDept(dept1);
emp4.setE_address("广东");
emp4.setE_name("小张");
emp4.setDept(dept1);
emp2.setE_address("湖北");
emp2.setE_name("小李");
emp2.setDept(dept2);
emp3.setE_address("广东");
emp3.setE_name("小邓");
emp3.setDept(dept3);
emp6.setE_address("广东");
emp6.setE_name("小胡");
session.save(emp1);
session.save(emp2);
session.save(emp3);
session.save(emp4);
session.save(emp6);
session.save(dept4);
tr.commit();
session.close();
}
-----
**hibernate插件的查询方式有下面几种**
1.唯一标识OID的检索方式
//session.get(对象.class,OID);
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Emp emp = session.get(Emp.class, 1);
System.out.println(emp.getDept().getD_name());
tr.commit();
session.close();
查询结果:研发部
2.对象导航的检索方式
/**
* 对象导航的方式
*/
@Test
public void test3(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Dept dept = session.get(Dept.class, 1);
System.out.println(dept.getEmps().size());
tr.commit();
session.close();
}
输出结果:2
值得注意的是,在这里我们借助了OID的方式获得了部门对象,并没有得到员工对象,但是我们依然打印出了该部门下员工的人数
3.HQL的检索方式
HQL全称为:Hibernate Query Language 是hibernate框架自己的查询体系
4.QBC的检索方式
QBC全称为:Query By Criteria //通过criteria接口的条件查询
5.原始SQL检索
hibernate支持原始SQL语句的查询,但是这与Hibernate的ORM思想不一致!
-------
**下面详细介绍下HQL检索与QBC检索**
-----
**HQL查询**
1.HQL查询概述:
HQL查询是一种面向对象的查询方式,符合ORM思想,底层采用映射的方式将HQL语句转为相应的SQL语句.
2.与SQL语句的区别与联系
底层依然是SQL语句,SQL操作的对象是字段和表,而HQL基于ORM思想操作的属性和对象
3.查询语句演示
3.1 基本查询格式
@Test
public void test4(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
List<Emp> list = session.createQuery("from Emp").list();
for (Emp emp : list) {
System.out.print(emp.getE_name()+",");
}
tr.commit();
session.close();
}
查询结果:小王,小李,小邓,小张,小胡,
注意,这里使用的是类名
3.2 HQL查询支持别名的方式
List<Emp> list = session.createQuery("select e from Emp e").list();
3.3 HQL排序查询
List<Emp> list = session.createQuery("from Emp order by e_id desc").list();
List<Emp> list = session.createQuery("from Emp order by e_id asc").list();
3.4 HQL分页查询
Query query = session.createQuery("from Emp");
//得到Qeury对象,设置开始页
query.setFirstResult(0);
//设置每一页显示条数
query.setMaxResults(3);
List<Emp> list = query.list();
for (Emp emp : list) {
System.out.println(emp);
}
结果:
Emp [e_id=1, e_name=小王, e_address=湖南, e_phone=null]
Emp [e_id=2, e_name=小李, e_address=湖北, e_phone=null]
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]
3.5 HQL按条件查询
Query query = session.createQuery("from Emp where e_name like ?");
query.setParameter(0, "%王%");
List<Emp> list = query.list();
for (Emp emp : list) {
System.out.println(emp);
}
结果是:Emp [e_id=1, e_name=小王, e_address=湖南, e_phone=null]
注意,此时占位符是从0开始的
3.6 HQL投影查询(其实就是选择几个想要的字段,无关字段不显示信息)
与 SELECT e_name,e_address FROM e_emp;的效果是一致的
@Test
public void test9(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Query query = session.createQuery("select e.e_name,e.e_address from Emp e");
List<Emp> list = query.list();
for (Emp emp : list) {
System.out.println(emp);
}
tr.commit();
session.close();
}
这样写会报错,因为返回的是一个Object类型的数组:java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to top.lingzhen.domain.Emp
HIbernate给我们提供另外的方式即使是单个字段仍然可以封装为对象,但是需要提供必要的构造方法,并且无参构造方法仍需保留
@Test
public void test10(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Query query = session.createQuery("select new Emp(e.e_name,e.e_address) from Emp e");
List<Emp> list = query.list();
for (Emp emp : list) {
System.out.println(emp.getE_name()+emp.getE_address());
}
tr.commit();
session.close();
}
此时Emp实体类变化为
public class Emp {
private Integer e_id;
private String e_name;
private String e_address;
private String e_phone;
private Dept dept;
public Emp(){
}
public Emp(String e_name,String e_address){
this.e_name=e_name;
this.e_address=e_address;
}
:
:
}
3.7 HQL查询之聚合函数查询
Query query = session.createQuery("select count(*) from Emp");
List<Number> list = query.list();
System.out.println(list.get(0).intValue());
注意:此时返回的泛型类型,其他聚合函数查询与上面类似
---
**QBC**查询
1.Queyr By Criteria查询是一种完全面向对象的查询
2.QBC的简单格式
List<Emp> list = session.createCriteria(Emp.class).list();
for (Emp emp : list) {
System.out.println(emp);
}
输出结果是
Emp [e_id=1, e_name=小王, e_address=湖南, e_phone=null]
Emp [e_id=2, e_name=小李, e_address=湖北, e_phone=null]
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]
Emp [e_id=4, e_name=小张, e_address=广东, e_phone=null]
Emp [e_id=5, e_name=小胡, e_address=广东, e_phone=null]
3.QBC的排序查询
@Test
public void test2(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Criteria criteria = session.createCriteria(Emp.class);
List<Emp> list = criteria.addOrder(Order.desc("e_id")).list();
for (Emp emp : list) {
System.out.println(emp);
}
}
Emp [e_id=5, e_name=小胡, e_address=广东, e_phone=null]
Emp [e_id=4, e_name=小张, e_address=广东, e_phone=null]
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]
Emp [e_id=2, e_name=小李, e_address=湖北, e_phone=null]
Emp [e_id=1, e_name=小王, e_address=湖南, e_phone=null]
QBC查询都是通过调用方法实现查询的,查询条件就是对应的类属性
4.QBC的分页查询
@Test
public void test3(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Criteria criteria = session.createCriteria(Emp.class);
criteria.setFirstResult(0);
criteria.setMaxResults(3);
List<Emp> list = criteria.list();
for (Emp emp : list) {
System.out.println(emp);
}
}
输出结果:
Emp [e_id=1, e_name=小王, e_address=湖南, e_phone=null]
Emp [e_id=2, e_name=小李, e_address=湖北, e_phone=null]
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]
5.QBC的条件查询
@Test
public void test4(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Criteria criteria = session.createCriteria(Emp.class);
criteria.addOrder(Order.desc("e_id"));
criteria.add(Restrictions.ge("e_id", 2));
List<Emp> list = criteria.list();
for (Emp emp : list) {
System.out.println(emp);
}
}
输出结果:
Emp [e_id=5, e_name=小胡, e_address=广东, e_phone=null]
Emp [e_id=4, e_name=小张, e_address=广东, e_phone=null]
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]
Emp [e_id=2, e_name=小李, e_address=湖北, e_phone=null]
如果想查询多个条件,可以使用Restrictions.or(Restrictions.XX(),Restrictions.XX()...)或者Restrictions.add(...)
Restrictions.eq //相等
Restrictions.gt // 大于号
Restrictions.ge // 大于等于
Restrictions.lt // 小于
Restrictions.le // 小于等于
Restrictions.between // 在之间
Restrictions.like // 模糊查询
Restrictions.in // 范围
Restrictions.and // 并且
Restrictions.or // 或者
6.QBC的聚合函数查询
需要借助Projection来进行查询
@Test
public void test5(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
Criteria criteria = session.createCriteria(Emp.class);
List<Number> list = criteria.setProjection(Projections.rowCount()).list();
System.out.println(list.get(0).intValue());
/*criteria.setProjection(null);//如果要执行注释部分的代码,需要执行这句,破坏其格式
List<Emp> list2 = criteria.addOrder(Order.desc("e_id")).list();
for (Emp emp : list2) {
System.out.println(emp);
}*/
}
----
**离线条件查询**
1.离线条件查询的意义:可以在WEB层不借助session获得查询对象,进行查询条件的拼接,最后执行把离线查询对象传到持久层就可以了,简化开发,不过在执行的适合还是需要session对象。
@Test
public void test6(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
DetachedCriteria forClass = DetachedCriteria.forClass(Emp.class);
DetachedCriteria add = forClass.add(Restrictions.ge("e_id",3));
//执行时仍需要session
List<Emp> list = add.getExecutableCriteria(session).list();
for (Emp emp : list) {
System.out.println(emp);
}
}
执行结果:
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]
Emp [e_id=4, e_name=小张, e_address=广东, e_phone=null]
Emp [e_id=5, e_name=小胡, e_address=广东, e_phone=null]
-----
**HQL的多表查询**
1.普通内连接
@Test
public void test6(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
//注意返回结果
List<Object[]> list=session.createQuery("from Emp e inner join e.dept").list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
}
2.使用fetch关键字的迫切内连接,能将查询结果封装为对象
@Test
public void test7(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
List<Emp> list=session.createQuery("from Emp e inner join fetch e.dept").list();
for (Emp emp : list) {
System.out.println(emp+"=="+emp.getDept().getD_name());
}
}
查询结果:
Emp [e_id=1, e_name=小王, e_address=湖南, e_phone=null]==研发部
Emp [e_id=4, e_name=小张, e_address=广东, e_phone=null]==研发部
Emp [e_id=2, e_name=小李, e_address=湖北, e_phone=null]==测试部
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]==运维部
3.左外连接,右外连接查询与上面相似
left join fetch //迫切左外连接
right join fetch //迫切右外连接
@Test
public void test8(){
Session session = HibernateUtils.getSession();
Transaction tr= session.beginTransaction();
List<Emp> list=session.createQuery("from Emp e left join fetch e.dept").list();
for (Emp emp : list) {
System.out.println(emp);
}
}
查询结果:
Emp [e_id=1, e_name=小王, e_address=湖南, e_phone=null]
Emp [e_id=2, e_name=小李, e_address=湖北, e_phone=null]
Emp [e_id=3, e_name=小邓, e_address=广东, e_phone=null]
Emp [e_id=4, e_name=小张, e_address=广东, e_phone=null]
Emp [e_id=5, e_name=小胡, e_address=广东, e_phone=null]
注意,不同的左右表查询最后的结果是不一致的,封装不上就为null
---