序言

         之前对hibernate中的查询总是搞混淆,不明白里面具体有哪些东西。就是因为缺少总结。在看这篇文章之前,你应该知道的是数据库的一些查询操作,多表查询等

                                            --WH

一、hibernate中的5种检索方式

      1.1、导航对象图检索方式  

          根据已经加载的对象导航到其他对象

          例如:在前面的各种映射关系中,实体类包含对其他类对象的引用。

              Dept d = (Dept) session.get(Dept.class,2);

              d.getStaffSet().size();  //d对象关联Staff集合,hibernate会自动检索Staff数据。如何检索的,看下面图中发送的sql语句。

                       

      1.2、OID检索方式

          按照对象的OID来检索对象

          例如:session.get()/session.load()  

          这个大家度很熟悉了,就不用在这里过多的阐述了。

      1.3、HQL检索方式

          HQL:Hibernate Query Language ,是面向对象的查询语言,它和SQL查询语言有些相似,在Hibernate提供的各种检索方式中,HQL是使用的最广的一种检索方式,

              注意:HQL操作的全是POJO类中的属性,而不是操作数据库表中的字段。

          1.3.1、在查询语句中设定各种查询条件

          1.3.2、支持投影查询,即仅检索出对象的部分属性

          1.3.3、支持分页查询

          1.3.4、支持连接查询

          1.3.5、支持分组查询,允许使用HAVING 和 GROUP BY 关键字

          1.3.6、提供内置聚集函数,如SUM(),MIN(),MAX()等

          1.3.7、能够调用用户定义的SQL函数或标准的SQL函数

          1.3.8、支持子查询

          1.3.9、支持动态绑定参数

          使用HQL检索步骤:

              1>获得session

              2>编写HQL

              3>通过session.createQuery(HQL)创建Query对象

              4>为Query对象设置条件参数(如果HQL中需要填充参数的话)

              5>执行查询

                  list():返回一个集合列表,有可能集合中装的是数组,有可能是POJO对象。

                  uniqueResult():返回一个查询结果,在已知查询结果只有一个或者0个时,使用是没有问题的,如果返回结果有多个,那么就会报异常

          实验

          创建环境,使用Dept和Staff的双向一对多关系,其中具体的代码就不在列举出来了。重点不在这里。原始记录Staff中有9条记录,都指向了Dept中id为2的部门。

           1.3.1、在查询语句中设定各种查询条件    

                 1.3.1.1、查询全部记录,没有查询条件         

1         //没有条件的hql,也就是查询全部记录。
2 String hql = "from Staff";
3 Query hqlQuery = session.createQuery(hql);
4 List<Staff> list = hqlQuery.list();
5 for(Staff staff : list){
6 System.out.println(staff.toString());
7 }

 

   //没有条件的hql,也就是查询全部记录。
2 String hql = "from Staff";
3 Query hqlQuery = session.createQuery(hql);
4 List<Staff> list = hqlQuery.list();
5 for(Staff staff : list){
6 System.out.println(staff.toString());
7 }

 

                 结果

              

                

                1.3.1.2、条件查询,查找出id=3的staff信息

1         String hql = "from Staff where id = 3";
2 Query hqlQuery = session.createQuery(hql);
3 //方式一
4 // List<Staff> list = hqlQuery.list();
5 // for(Staff staff : list){
6 // System.out.println(staff.toString());
7 // }
8 //方式二,已知只有一条数据,使用uniqueResult
9 Staff staff = (Staff) hqlQuery.uniqueResult();
10 System.out.println(staff.toString());
11
12 //结果
13 Hibernate:
14 select
15 staff0_.id as id1_,
16 staff0_.name as name1_,
17 staff0_.deptId as deptId1_
18 from
19 staff staff0_
20 where
21 staff0_.id=3
22 //因为是立即检索,所有有了这条语句,这里不做解释,
23 Hibernate:
24 select
25 dept0_.id as id0_0_,
26 dept0_.name as name0_0_
27 from
28 dept dept0_
29 where
30 dept0_.id=?
31 //查询到了响应结果
32 Staff [id=3, name=qqq2, dept=oneToMany.Dept@cc0e21a]
 1         String hql = "from Staff where id = 3";
2 Query hqlQuery = session.createQuery(hql);
3 //方式一
4 // List<Staff> list = hqlQuery.list();
5 // for(Staff staff : list){
6 // System.out.println(staff.toString());
7 // }
8 //方式二,已知只有一条数据,使用uniqueResult
9 Staff staff = (Staff) hqlQuery.uniqueResult();
10 System.out.println(staff.toString());
11
12 //结果
13 Hibernate:
14 select
15 staff0_.id as id1_,
16 staff0_.name as name1_,
17 staff0_.deptId as deptId1_
18 from
19 staff staff0_
20 where
21 staff0_.id=3
22 //因为是立即检索,所有有了这条语句,这里不做解释,
23 Hibernate:
24 select
25 dept0_.id as id0_0_,
26 dept0_.name as name0_0_
27 from
28 dept dept0_
29 where
30 dept0_.id=?
31 //查询到了响应结果
32 Staff [id=3, name=qqq2, dept=oneToMany.Dept@cc0e21a]

   

           1.3.2、支持投影查询,即仅检索出对象的部分属性

                  也就是不需要将表中所有的字段度查询出来,只查询出对象的部分属性,这就是投影查询

                1.3.2.1、什么度不使用,直接查询,得到的结果就是将查到的属性全放到list集合中。这只使用于检索对象的一个属性,如果多个属性,就得需要用别的方式进行封装

 1         String hql = "select name from Staff";
2 Query hqlQuery = session.createQuery(hql);
3 List list = hqlQuery.list(); //集合中存放的是String,也就是name属性值。
4 System.out.println(list);
5
6 //结果
7 Hibernate:
8 select
9 staff0_.name as col_0_0_
10 from
11 staff staff0_
12 [qqq1, qqq2, qqq3, qqq4, qqq5, qqq6, qqq7, qqq8, qqq9]
 1         String hql = "select name from Staff";
2 Query hqlQuery = session.createQuery(hql);
3 List list = hqlQuery.list(); //集合中存放的是String,也就是name属性值。
4 System.out.println(list);
5
6 //结果
7 Hibernate:
8 select
9 staff0_.name as col_0_0_
10 from
11 staff staff0_
12 [qqq1, qqq2, qqq3, qqq4, qqq5, qqq6, qqq7, qqq8, qqq9]

                1.3.2.2、使用new List()或者new Map()或new Staff()将返回的值给封装起来

    使用new Staff()

 1         //使用new Staff(id,name)的前提是Staff的实体类中id和name这个构造器。反则报错
2 String hql = "select new Staff(id,name) from Staff";
3 Query hqlQuery = session.createQuery(hql);
4 List<Staff> list = hqlQuery.list(); //集合中存放的是Staff数组。。
5 System.out.println(list);
6 //结果
7 Hibernate:
8 select
9 staff0_.id as col_0_0_,
10 staff0_.name as col_1_0_
11 from
12 staff staff0_
13 [Staff [id=2, name=qqq1, dept=null], Staff [id=3, name=qqq2, dept=null], Staff [id=4, name=qqq3, dept=null], Staff [id=5, name=qqq4, dept=null],
14 Staff [id=6, name=qqq5, dept=null], Staff [id=7, name=qqq6, dept=null], Staff [id=8, name=qqq7, dept=null], Staff [id=9, name=qqq8, dept=null],
15 Staff [id=10, name=qqq9, dept=null]]
 1         //使用new Staff(id,name)的前提是Staff的实体类中id和name这个构造器。反则报错
2 String hql = "select new Staff(id,name) from Staff";
3 Query hqlQuery = session.createQuery(hql);
4 List<Staff> list = hqlQuery.list(); //集合中存放的是Staff数组。。
5 System.out.println(list);
6 //结果
7 Hibernate:
8 select
9 staff0_.id as col_0_0_,
10 staff0_.name as col_1_0_
11 from
12 staff staff0_
13 [Staff [id=2, name=qqq1, dept=null], Staff [id=3, name=qqq2, dept=null], Staff [id=4, name=qqq3, dept=null], Staff [id=5, name=qqq4, dept=null],
14 Staff [id=6, name=qqq5, dept=null], Staff [id=7, name=qqq6, dept=null], Staff [id=8, name=qqq7, dept=null], Staff [id=9, name=qqq8, dept=null],
15 Staff [id=10, name=qqq9, dept=null]]

    使用new List()

 1         //将查询到的结果存放在list集合中,形式如 List[数组1,数组2...]  数组1[id,name]
2 String hql = "select new List(id,name) from Staff";
3 Query hqlQuery = session.createQuery(hql);
4 List list = hqlQuery.list(); //集合中存放的是id,name数组。。
5 System.out.println(list);
6
7 //结果
8 Hibernate:
9 select
10 staff0_.id as col_0_0_,
11 staff0_.name as col_1_0_
12 from
13 staff staff0_
14 [[2, qqq1], [3, qqq2], [4, qqq3], [5, qqq4], [6, qqq5],
15 [7, qqq6], [8, qqq7], [9, qqq8], [10, qqq9]]
 1         //将查询到的结果存放在list集合中,形式如 List[数组1,数组2...]  数组1[id,name]
2 String hql = "select new List(id,name) from Staff";
3 Query hqlQuery = session.createQuery(hql);
4 List list = hqlQuery.list(); //集合中存放的是id,name数组。。
5 System.out.println(list);
6
7 //结果
8 Hibernate:
9 select
10 staff0_.id as col_0_0_,
11 staff0_.name as col_1_0_
12 from
13 staff staff0_
14 [[2, qqq1], [3, qqq2], [4, qqq3], [5, qqq4], [6, qqq5],
15 [7, qqq6], [8, qqq7], [9, qqq8], [10, qqq9]]

    使用new Map()

   //将查询到的结果用map封装,然后放到list集合中,
String hql = "select new Map(id,name) from Staff";
Query hqlQuery = session.createQuery(hql);
List list = hqlQuery.list(); //集合中存放的是id,name数组。。
System.out.println(list); //结果
Hibernate:
select
staff0_.id as col_0_0_,
staff0_.name as col_1_0_
from
staff staff0_
[{1=qqq1, 0=2}, {1=qqq2, 0=3}, {1=qqq3, 0=4},
{1=qqq4, 0=5}, {1=qqq5, 0=6}, {1=qqq6, 0=7},
{1=qqq7, 0=8}, {1=qqq8, 0=9}, {1=qqq9, 0=10}]
        //将查询到的结果用map封装,然后放到list集合中,
String hql = "select new Map(id,name) from Staff";
Query hqlQuery = session.createQuery(hql);
List list = hqlQuery.list(); //集合中存放的是id,name数组。。
System.out.println(list); //结果
Hibernate:
select
staff0_.id as col_0_0_,
staff0_.name as col_1_0_
from
staff staff0_
[{1=qqq1, 0=2}, {1=qqq2, 0=3}, {1=qqq3, 0=4},
{1=qqq4, 0=5}, {1=qqq5, 0=6}, {1=qqq6, 0=7},
{1=qqq7, 0=8}, {1=qqq8, 0=9}, {1=qqq9, 0=10}]

            1.3.3、支持分页查询

                使用setFirst()和setMaxResult()分别设置起始索引和拿去数据的总数。跟limit m,n 是一样的

   String hql = "from Staff";
Query hqlQuery = session.createQuery(hql);
//从数据库表中取出第三条到第六条记录来。相当于MySQL的limit 2,3;
hqlQuery.setFirstResult(2);
hqlQuery.setMaxResults(3);
List<Staff> list = hqlQuery.list(); //集合中存放的是id,name数组。。
for(Staff staff : list){
System.out.println(staff.toString());
} //结果
Hibernate:
select
staff0_.id as id1_,
staff0_.name as name1_,
staff0_.deptId as deptId1_
from
staff staff0_ limit ?,
?
Hibernate:
select
dept0_.id as id0_0_,
dept0_.name as name0_0_
from
dept dept0_
where
dept0_.id=?
//由于数据库表中没有id=1的数据,所以拿到的记录是从id=4开始。也就是从第三条到第六条
Staff [id=4, name=qqq3, dept=oneToMany.Dept@2bf11e9f]
Staff [id=5, name=qqq4, dept=oneToMany.Dept@2bf11e9f]
Staff [id=6, name=qqq5, dept=oneToMany.Dept@2bf11e9f]
        String hql = "from Staff";
Query hqlQuery = session.createQuery(hql);
//从数据库表中取出第三条到第六条记录来。相当于MySQL的limit 2,3;
hqlQuery.setFirstResult(2);
hqlQuery.setMaxResults(3);
List<Staff> list = hqlQuery.list(); //集合中存放的是id,name数组。。
for(Staff staff : list){
System.out.println(staff.toString());
} //结果
Hibernate:
select
staff0_.id as id1_,
staff0_.name as name1_,
staff0_.deptId as deptId1_
from
staff staff0_ limit ?,
?
Hibernate:
select
dept0_.id as id0_0_,
dept0_.name as name0_0_
from
dept dept0_
where
dept0_.id=?
//由于数据库表中没有id=1的数据,所以拿到的记录是从id=4开始。也就是从第三条到第六条
Staff [id=4, name=qqq3, dept=oneToMany.Dept@2bf11e9f]
Staff [id=5, name=qqq4, dept=oneToMany.Dept@2bf11e9f]
Staff [id=6, name=qqq5, dept=oneToMany.Dept@2bf11e9f]

  

            1.3.4、支持连接查询

                支持7种连接写法。

                1.3.4.1、内连接 inner join  可以省略inner,直接join

 1         //注意,hql操作的是POJO,而不是表中字段,所以s.dept这里不能写成Dept或者dept,
2 //不用写ON后面的连接条件,因为hibernate映射文件我们已经全部写好了。
3 String hql = "from Dept d inner join d.staffSet";
4 Query hqlQuery = session.createQuery(hql);
5 //这里的泛型不能是Staff了。结合了两张表,集合中存放的是Object[],数组中存放的是Staff和Dept实体
6 List<Object[]> list = hqlQuery.list(); //集合中存放的是id,name数组。。
7 Object[] o = list.get(0);
8 System.out.println(o);
9 //注意:其中Dept和Staff中都没有对方实体的引用。因为这个是左外连接,生成了新的表。
10 System.out.println(((Dept)o[0]).getName());//获得Dept实体的name
11 System.out.println(((Staff)o[1]).getName());//或者Staff的name
12
13 //结果
14 //左外连接的语句,并且为我们加上了ON之后的语句
15 Hibernate:
16 select
17 dept0_.id as id0_0_,
18 staffset1_.id as id1_1_,
19 dept0_.name as name0_0_,
20 staffset1_.name as name1_1_,
21 staffset1_.deptId as deptId1_1_
22 from
23 dept dept0_
24 inner join
25 staff staffset1_
26 on dept0_.id=staffset1_.deptId
27 //这个是list中第一个Object[] 不用看他的格式,只要知道他有代表着Dept和Staff实体
28 [Ljava.lang.Object;@44eef74f
29 1部门
30 qqq1
 1         //注意,hql操作的是POJO,而不是表中字段,所以s.dept这里不能写成Dept或者dept,
2 //不用写ON后面的连接条件,因为hibernate映射文件我们已经全部写好了。
3 String hql = "from Dept d inner join d.staffSet";
4 Query hqlQuery = session.createQuery(hql);
5 //这里的泛型不能是Staff了。结合了两张表,集合中存放的是Object[],数组中存放的是Staff和Dept实体
6 List<Object[]> list = hqlQuery.list(); //集合中存放的是id,name数组。。
7 Object[] o = list.get(0);
8 System.out.println(o);
9 //注意:其中Dept和Staff中都没有对方实体的引用。因为这个是左外连接,生成了新的表。
10 System.out.println(((Dept)o[0]).getName());//获得Dept实体的name
11 System.out.println(((Staff)o[1]).getName());//或者Staff的name
12
13 //结果
14 //左外连接的语句,并且为我们加上了ON之后的语句
15 Hibernate:
16 select
17 dept0_.id as id0_0_,
18 staffset1_.id as id1_1_,
19 dept0_.name as name0_0_,
20 staffset1_.name as name1_1_,
21 staffset1_.deptId as deptId1_1_
22 from
23 dept dept0_
24 inner join
25 staff staffset1_
26 on dept0_.id=staffset1_.deptId
27 //这个是list中第一个Object[] 不用看他的格式,只要知道他有代表着Dept和Staff实体
28 [Ljava.lang.Object;@44eef74f
29 1部门
30 qqq1

                        

                1.3.4.2、迫切内连接 inner join fetch

                    内连接返回的list中是Object[],而迫切内连接返回的list中是POJO类对象

 1         //注意,hql操作的是POJO,而不是表中字段,所以s.dept这里不能写成Dept或者dept,
2 //不用写ON后面的连接条件,因为hibernate映射文件我们已经全部写好了。
3 String hql = "from Dept d inner join fetch d.staffSet";
4 Query hqlQuery = session.createQuery(hql);
5 //使用的是迫切内连接,其list中放的就是Dept对象了,注意并没有包含staffSet。放的是from后面跟的POJO,如果是Staff。那么这里就放的Staff。
6 //所以自己重写了toString方法的人这里会报错,
7 List list = hqlQuery.list(); //集合中存放的是Dept。
8 System.out.println(list);
9
10 //结果
11 Hibernate:
12 select
13 dept0_.id as id0_0_,
14 staffset1_.id as id1_1_,
15 dept0_.name as name0_0_,
16 staffset1_.name as name1_1_,
17 staffset1_.deptId as deptId1_1_,
18 staffset1_.deptId as deptId0_0__,
19 staffset1_.id as id0__
20 from
21 dept dept0_
22 inner join
23 staff staffset1_
24 on dept0_.id=staffset1_.deptId
25 //返回那么多相同的原因是内连接,Staff中有9条记录,则部门这边也会显示9条,所以这里重复了9次。可以是用DISTINCT关键字去除重复的记录
26 [Dept [id=2, name=1部门], Dept [id=2, name=1部门], Dept [id=2, name=1部门], Dept [id=2, name=1部门], Dept [id=2, name=1部门], Dept [id=2, name=1部门], Dept [id=2, name=1部门], Dept [id=2, name=1部门], Dept [id=2, name=1部门]]
 1         //注意,hql操作的是POJO,而不是表中字段,所以s.dept这里不能写成Dept或者dept,
2 //不用写ON后面的连接条件,因为hibernate映射文件我们已经全部写好了。
3 String hql = "from Dept d inner join fetch d.staffSet";
4 Query hqlQuery = session.createQuery(hql);
5 //使用的是迫切内连接,其list中放的就是Dept对象了,注意并没有包含staffSet。放的是from后面跟的POJO,如果是Staff。那么这里就放的Staff。
6 //所以自己重写了toString方法的人这里会报错,
7 List list = hqlQuery.list(); //集合中存放的是Dept。
8 System.out.println(list);
9
10 //结果
11 Hibernate:
12 select
13 dept0_.id as id0_0_,
14 staffset1_.id as id1_1_,
15 dept0_.name as name0_0_,
16 staffset1_.name as name1_1_,
17 staffset1_.deptId as deptId1_1_,
18 staffset1_.deptId as deptId0_0__,
19 staffset1_.id as id0__
20 from
21 dept dept0_
22 inner join
23 staff staffset1_
24 on dept0_.id=staffset1_.deptId
25 //返回那么多相同的原因是内连接,Staff中有9条记录,则部门这边也会显示9条,所以这里重复了9次。可以是用DISTINCT关键字去除重复的记录
26 [Dept [id=2, name=1部门], Dept [id=2, name=1部门], Dept [id=2, name=1部门], Dept [id=2, name=1部门], Dept [id=2, name=1部门], Dept [id=2, name=1部门], Dept [id=2, name=1部门], Dept [id=2, name=1部门], Dept [id=2, name=1部门]]

                要想得到不重复的记录,那么就将hql改为"select distinct d from Dept d inner join fetch d.staffSet";

                1.3.4.3、隐式内连接 不写任何关键字,完成表连接

                    其实就是通过where连接两张表。很简单。

 1         //隐式内连接,其实就是最普通的通过where来连接两张表,如何看了MySQL的表查询操作,
2 //这个应该很简单,但是这里只能通过多方找一方,因为一方存放的是集合,就不能向下面这样赋值
3 String hql = "from Staff s where s.dept.name = ?";
4 Query hqlQuery = session.createQuery(hql);
5 hqlQuery.setParameter(0, "1部门");
6
7 List list = hqlQuery.list(); //集合中存放的是Dept。
8 System.out.println(list);
9 //结果
10 Hibernate:
11 select
12 staff0_.id as id1_,
13 staff0_.name as name1_,
14 staff0_.deptId as deptId1_
15 from
16 staff staff0_ cross
17 join
18 dept dept1_
19 where
20 staff0_.deptId=dept1_.id
21 and dept1_.name=?
22 [Staff [id=2, name=qqq1], Staff [id=3, name=qqq2], Staff [id=4, name=qqq3], Staff [id=5, name=qqq4], Staff [id=6, name=qqq5], Staff [id=7, name=qqq6], Staff [id=8, name=qqq7], Staff [id=9, name=qqq8], Staff [id=10, name=qqq9]]
 1         //隐式内连接,其实就是最普通的通过where来连接两张表,如何看了MySQL的表查询操作,
2 //这个应该很简单,但是这里只能通过多方找一方,因为一方存放的是集合,就不能向下面这样赋值
3 String hql = "from Staff s where s.dept.name = ?";
4 Query hqlQuery = session.createQuery(hql);
5 hqlQuery.setParameter(0, "1部门");
6
7 List list = hqlQuery.list(); //集合中存放的是Dept。
8 System.out.println(list);
9 //结果
10 Hibernate:
11 select
12 staff0_.id as id1_,
13 staff0_.name as name1_,
14 staff0_.deptId as deptId1_
15 from
16 staff staff0_ cross
17 join
18 dept dept1_
19 where
20 staff0_.deptId=dept1_.id
21 and dept1_.name=?
22 [Staff [id=2, name=qqq1], Staff [id=3, name=qqq2], Staff [id=4, name=qqq3], Staff [id=5, name=qqq4], Staff [id=6, name=qqq5], Staff [id=7, name=qqq6], Staff [id=8, name=qqq7], Staff [id=9, name=qqq8], Staff [id=10, name=qqq9]]

                1.3.4.4、左外连接,left outer join,可以省略outer,直接left join

 1         //左外连接,自己脑袋里想一下在左外连接的时候,表会是什么样子。通过前面看到的内连接
2 //和迫切内连接就应该知道这里左外连接list中存放的是什么,就是Object[]
3 String hql = "from Staff s left outer join s.dept";
4 Query hqlQuery = session.createQuery(hql);
5
6 List<Object[]> list = hqlQuery.list();
7 Object[] object = list.get(0);
8 System.out.println(((Staff)object[0]).getName());
9 System.out.println(((Dept)object[1]).getName());
10
11 //结果
12 Hibernate:
13 select
14 staff0_.id as id1_0_,
15 dept1_.id as id0_1_,
16 staff0_.name as name1_0_,
17 staff0_.deptId as deptId1_0_,
18 dept1_.name as name0_1_
19 from
20 staff staff0_
21 left outer join
22 dept dept1_
23 on staff0_.deptId=dept1_.id
24 qqq1
25 1部门
 1         //左外连接,自己脑袋里想一下在左外连接的时候,表会是什么样子。通过前面看到的内连接
2 //和迫切内连接就应该知道这里左外连接list中存放的是什么,就是Object[]
3 String hql = "from Staff s left outer join s.dept";
4 Query hqlQuery = session.createQuery(hql);
5
6 List<Object[]> list = hqlQuery.list();
7 Object[] object = list.get(0);
8 System.out.println(((Staff)object[0]).getName());
9 System.out.println(((Dept)object[1]).getName());
10
11 //结果
12 Hibernate:
13 select
14 staff0_.id as id1_0_,
15 dept1_.id as id0_1_,
16 staff0_.name as name1_0_,
17 staff0_.deptId as deptId1_0_,
18 dept1_.name as name0_1_
19 from
20 staff staff0_
21 left outer join
22 dept dept1_
23 on staff0_.deptId=dept1_.id
24 qqq1
25 1部门

                1.3.4.5、迫切左外连接, left outer join fetch

                  一样的区别,就是list中存放的是POJO对象了

 1         //迫切左外连接,就是list中存放的是POJO对象。在这里存放的是Staff。
2 String hql = "from Staff s left outer join fetch s.dept";
3 Query hqlQuery = session.createQuery(hql);
4
5 List list = hqlQuery.list();
6 System.out.println(list);
7
8 //结果
9 Hibernate:
10 select
11 staff0_.id as id1_0_,
12 dept1_.id as id0_1_,
13 staff0_.name as name1_0_,
14 staff0_.deptId as deptId1_0_,
15 dept1_.name as name0_1_
16 from
17 staff staff0_
18 left outer join
19 dept dept1_
20 on staff0_.deptId=dept1_.id
21 [Staff [id=2, name=qqq1], Staff [id=3, name=qqq2], Staff [id=4, name=qqq3], Staff [id=5, name=qqq4], Staff [id=6, name=qqq5],
22 Staff [id=7, name=qqq6], Staff [id=8, name=qqq7], Staff [id=9, name=qqq8], Staff [id=10, name=qqq9]]
 1         //迫切左外连接,就是list中存放的是POJO对象。在这里存放的是Staff。
2 String hql = "from Staff s left outer join fetch s.dept";
3 Query hqlQuery = session.createQuery(hql);
4
5 List list = hqlQuery.list();
6 System.out.println(list);
7
8 //结果
9 Hibernate:
10 select
11 staff0_.id as id1_0_,
12 dept1_.id as id0_1_,
13 staff0_.name as name1_0_,
14 staff0_.deptId as deptId1_0_,
15 dept1_.name as name0_1_
16 from
17 staff staff0_
18 left outer join
19 dept dept1_
20 on staff0_.deptId=dept1_.id
21 [Staff [id=2, name=qqq1], Staff [id=3, name=qqq2], Staff [id=4, name=qqq3], Staff [id=5, name=qqq4], Staff [id=6, name=qqq5],
22 Staff [id=7, name=qqq6], Staff [id=8, name=qqq7], Staff [id=9, name=qqq8], Staff [id=10, name=qqq9]]

                1.3.4.6、右外连接:right outer join

                  知道左外连接,右外连接也就会了。

 1         //右外连接,就是list中存放的是Object[]
2 String hql = "from Staff s right outer join s.dept";
3 Query hqlQuery = session.createQuery(hql);
4
5 List<Object[]> list = hqlQuery.list();
6 System.out.println(list);
7
8 //结果
9 Hibernate:
10 select
11 staff0_.id as id1_0_,
12 dept1_.id as id0_1_,
13 staff0_.name as name1_0_,
14 staff0_.deptId as deptId1_0_,
15 dept1_.name as name0_1_
16 from
17 staff staff0_
18 right outer join
19 dept dept1_
20 on staff0_.deptId=dept1_.id
21 [[Ljava.lang.Object;@11e04129, [Ljava.lang.Object;@19d5f3ea, [Ljava.lang.Object;@2d8094e6, [Ljava.lang.Object;@54af9f60, [Ljava.lang.Object;@5608830f, [Ljava.lang.Object;@48d479e9, [Ljava.lang.Object;@758fd559, [Ljava.lang.Object;@3600025b, [Ljava.lang.Object;@3a9ac00f]
 1         //右外连接,就是list中存放的是Object[]
2 String hql = "from Staff s right outer join s.dept";
3 Query hqlQuery = session.createQuery(hql);
4
5 List<Object[]> list = hqlQuery.list();
6 System.out.println(list);
7
8 //结果
9 Hibernate:
10 select
11 staff0_.id as id1_0_,
12 dept1_.id as id0_1_,
13 staff0_.name as name1_0_,
14 staff0_.deptId as deptId1_0_,
15 dept1_.name as name0_1_
16 from
17 staff staff0_
18 right outer join
19 dept dept1_
20 on staff0_.deptId=dept1_.id
21 [[Ljava.lang.Object;@11e04129, [Ljava.lang.Object;@19d5f3ea, [Ljava.lang.Object;@2d8094e6, [Ljava.lang.Object;@54af9f60, [Ljava.lang.Object;@5608830f, [Ljava.lang.Object;@48d479e9, [Ljava.lang.Object;@758fd559, [Ljava.lang.Object;@3600025b, [Ljava.lang.Object;@3a9ac00f]

                1.3.4.7、交叉连接,会产生笛卡尔积。

                  什么是笛卡尔积?将两张表连接起来,比如一张表中有3条记录,另一张表中也有3条记录,那么连接之后,就会出现9条数据,其中就有一些重复的数据,拿实例说话,班级和学生,有三个学生A,B,C,有两个班级E,F,连接起来后,就会出现笛卡尔积,6条数据,其中会出现这样的数据,A,E 、A,F、B,E、B,F、C,E、C,F, A,B,C就重复出现了,即在E班级,又在F班级,这样就不合理。这就是所说的笛卡尔积。

                  由于dept中就一条记录,无法展示出笛卡尔积,所以手动增加一条dept的记录。然后在进行交叉连接。就会出现笛卡尔积,

 1         //直接将两张表简单相连,出现笛卡尔积,因为从结果中可以看到,list集合中有18个数组,说明有18条记录
2 String hql = "from Staff,Dept";
3 Query hqlQuery = session.createQuery(hql);
4
5 List list = hqlQuery.list();
6 System.out.println(list);
7
8 //结果
9 Hibernate:
10 select
11 staff0_.id as id1_0_,
12 dept1_.id as id0_1_,
13 staff0_.name as name1_0_,
14 staff0_.deptId as deptId1_0_,
15 dept1_.name as name0_1_
16 from
17 staff staff0_ cross
18 join
19 dept dept1_
20 //18个数组
21 [[Ljava.lang.Object;@42064d82, [Ljava.lang.Object;@2bcab3ab, [Ljava.lang.Object;@8d9b603, [Ljava.lang.Object;@d3c837f, [Ljava.lang.Object;@7fdd0da2, [Ljava.lang.Object;@9aa4843, [Ljava.lang.Object;@a6e2baa, [Ljava.lang.Object;@46f4ab3f, [Ljava.lang.Object;@6916d97d, [Ljava.lang.Object;@5b20d371, [Ljava.lang.Object;@4819ce74, [Ljava.lang.Object;@164146a7, [Ljava.lang.Object;@1785895b, [Ljava.lang.Object;@3ffcc16d, [Ljava.lang.Object;@6afefbec, [Ljava.lang.Object;@a4d79d5, [Ljava.lang.Object;@6479943b, [Ljava.lang.Object;@69f2e105]
 1         //直接将两张表简单相连,出现笛卡尔积,因为从结果中可以看到,list集合中有18个数组,说明有18条记录
2 String hql = "from Staff,Dept";
3 Query hqlQuery = session.createQuery(hql);
4
5 List list = hqlQuery.list();
6 System.out.println(list);
7
8 //结果
9 Hibernate:
10 select
11 staff0_.id as id1_0_,
12 dept1_.id as id0_1_,
13 staff0_.name as name1_0_,
14 staff0_.deptId as deptId1_0_,
15 dept1_.name as name0_1_
16 from
17 staff staff0_ cross
18 join
19 dept dept1_
20 //18个数组
21 [[Ljava.lang.Object;@42064d82, [Ljava.lang.Object;@2bcab3ab, [Ljava.lang.Object;@8d9b603, [Ljava.lang.Object;@d3c837f, [Ljava.lang.Object;@7fdd0da2, [Ljava.lang.Object;@9aa4843, [Ljava.lang.Object;@a6e2baa, [Ljava.lang.Object;@46f4ab3f, [Ljava.lang.Object;@6916d97d, [Ljava.lang.Object;@5b20d371, [Ljava.lang.Object;@4819ce74, [Ljava.lang.Object;@164146a7, [Ljava.lang.Object;@1785895b, [Ljava.lang.Object;@3ffcc16d, [Ljava.lang.Object;@6afefbec, [Ljava.lang.Object;@a4d79d5, [Ljava.lang.Object;@6479943b, [Ljava.lang.Object;@69f2e105]

                

               注意:上面的连接中很多是使用一个引用就代表了相对应的表,比如" from Dept d inner join d.staffSet " d.staffSet就好像代表了Staff的这张表,实际上就是代表了Staff这张表,这样理解,from Dept 就从Dept表中找出了所有记录,就打比方,找到了Dept表中的2部门,在2部门中有多少staff呢,可以全部找出来,在我们所说的环境下,正好就staff就全部在该部门中,那么就找到了Staff表中的所有staff,也就是相当于是Staff这张表了,就算2部门没有包括所有的staff,那么还有其他部门,肯定包括了剩下的staff,也就是说,不管怎么样,度能把staff全部找到,所以d.staffSet就相当于Staff表了。以此类推,其他hql语句中的这里也是这样理解的。

             1.3.5、支持分组查询,允许使用HAVING 和 GROUP BY 关键字

                

1         //s.dept.id 就相当于操作Staff表中的deptId。看发送的sql语句就能知道。
2 //原因是Staff这个类中并没有deptId表字段属性,但是有dept的引用变量,其dept的id
3 //也就是Staff中的deptId值,只是中间转换了一步,也不是很难理解。
4 String hql = "from Staff s group by s.dept.id";
5 Query hqlQuery = session.createQuery(hql);
6 List list = hqlQuery.list();
7 System.out.println(list);
8
9 //结果
10 Hibernate:
11 select
12 staff0_.id as id1_,
13 staff0_.name as name1_,
14 staff0_.deptId as deptId1_
15 from
16 staff staff0_
17 group by
18 staff0_.deptId
19 //分组后显示的就是第一个值。由于数据问题,9个staff度是在一个部门,所以通过部门分组,就只能得到一个分组。
20 [Staff [id=2, name=qqq1]]
 1         //s.dept.id 就相当于操作Staff表中的deptId。看发送的sql语句就能知道。
2 //原因是Staff这个类中并没有deptId表字段属性,但是有dept的引用变量,其dept的id
3 //也就是Staff中的deptId值,只是中间转换了一步,也不是很难理解。
4 String hql = "from Staff s group by s.dept.id";
5 Query hqlQuery = session.createQuery(hql);
6 List list = hqlQuery.list();
7 System.out.println(list);
8
9 //结果
10 Hibernate:
11 select
12 staff0_.id as id1_,
13 staff0_.name as name1_,
14 staff0_.deptId as deptId1_
15 from
16 staff staff0_
17 group by
18 staff0_.deptId
19 //分组后显示的就是第一个值。由于数据问题,9个staff度是在一个部门,所以通过部门分组,就只能得到一个分组。
20 [Staff [id=2, name=qqq1]]

             1.3.6、提供内置聚集函数,如SUM(),MIN(),MAX()等

这个例子中不好使用这几个函数。。。所以这里不演示了,很简单。hql和sql差不太多。

             1.3.7、能够调用用户定义的SQL函数或标准的SQL函数

这个跟上面的一样,SQL中函数有很多。也就是说hql能够使用sql中的函数

             1.3.8、支持子查询        

 1         //子查询操作,实际意义:Staff表中的staff所在的部门编号,跟Dept中所有的部门编号有对应的,就将其staff取出。
2 String hql = "from Staff s where s.dept.id IN (select id from Dept)";
3 Query hqlQuery = session.createQuery(hql);
4 List list = hqlQuery.list();
5 System.out.println(list);
6 //结果
7 Hibernate:
8 select
9 staff0_.id as id1_,
10 staff0_.name as name1_,
11 staff0_.deptId as deptId1_
12 from
13 staff staff0_
14 where
15 staff0_.deptId in (
16 select
17 dept1_.id
18 from
19 dept dept1_
20 )
21 [Staff [id=2, name=qqq1], Staff [id=3, name=qqq2], Staff [id=4, name=qqq3], Staff [id=5, name=qqq4], Staff [id=6, name=qqq5], Staff [id=7, name=qqq6], Staff [id=8, name=qqq7], Staff [id=9, name=qqq8], Staff [id=10, name=qqq9]]
 1         //子查询操作,实际意义:Staff表中的staff所在的部门编号,跟Dept中所有的部门编号有对应的,就将其staff取出。
2 String hql = "from Staff s where s.dept.id IN (select id from Dept)";
3 Query hqlQuery = session.createQuery(hql);
4 List list = hqlQuery.list();
5 System.out.println(list);
6 //结果
7 Hibernate:
8 select
9 staff0_.id as id1_,
10 staff0_.name as name1_,
11 staff0_.deptId as deptId1_
12 from
13 staff staff0_
14 where
15 staff0_.deptId in (
16 select
17 dept1_.id
18 from
19 dept dept1_
20 )
21 [Staff [id=2, name=qqq1], Staff [id=3, name=qqq2], Staff [id=4, name=qqq3], Staff [id=5, name=qqq4], Staff [id=6, name=qqq5], Staff [id=7, name=qqq6], Staff [id=8, name=qqq7], Staff [id=9, name=qqq8], Staff [id=10, name=qqq9]]

            1.3.9、条件查询,给hql中动态设置参数的两种方式

                    方式一:from Staff where id = ? 使用?代替所需要填入的值,在下面设置值时则从0开始算起,第一个?是处于0的位置,如果有两个?号,则使用0,1索引号来插入值。

 1         String hql = "from Staff where id = ?";
2 Query hqlQuery = session.createQuery(hql);
3
4 hqlQuery.setParameter(0, 4);
5
6 Staff staff = (Staff) hqlQuery.uniqueResult();
7 System.out.println(staff.toString());
8
9 //结果
10 Hibernate:
11 select
12 staff0_.id as id1_,
13 staff0_.name as name1_,
14 staff0_.deptId as deptId1_
15 from
16 staff staff0_
17 where
18 staff0_.id=?
19 Hibernate:
20 select
21 dept0_.id as id0_0_,
22 dept0_.name as name0_0_
23 from
24 dept dept0_
25 where
26 dept0_.id=?
27 Staff [id=4, name=qqq3, dept=oneToMany.Dept@f1cb8ac]
 1         String hql = "from Staff where id = ?";
2 Query hqlQuery = session.createQuery(hql);
3
4 hqlQuery.setParameter(0, 4);
5
6 Staff staff = (Staff) hqlQuery.uniqueResult();
7 System.out.println(staff.toString());
8
9 //结果
10 Hibernate:
11 select
12 staff0_.id as id1_,
13 staff0_.name as name1_,
14 staff0_.deptId as deptId1_
15 from
16 staff staff0_
17 where
18 staff0_.id=?
19 Hibernate:
20 select
21 dept0_.id as id0_0_,
22 dept0_.name as name0_0_
23 from
24 dept dept0_
25 where
26 dept0_.id=?
27 Staff [id=4, name=qqq3, dept=oneToMany.Dept@f1cb8ac]

                    方式二:from Staff where id = :id  使用":id"这个名字来表示插入值的名称,在下面则不用索引号来确定插入值的位置,直接是使用这个别称

  String hql = "from Staff where id = :id";
2 Query hqlQuery = session.createQuery(hql);
3
4 hqlQuery.setParameter("id", 4);
5
6 Staff staff = (Staff) hqlQuery.uniqueResult();
7 System.out.println(staff.toString());
8
9 //结果
10 Hibernate:
11 select
12 staff0_.id as id1_,
13 staff0_.name as name1_,
14 staff0_.deptId as deptId1_
15 from
16 staff staff0_
17 where
18 staff0_.id=?
19 Hibernate:
20 select
21 dept0_.id as id0_0_,
22 dept0_.name as name0_0_
23 from
24 dept dept0_
25 where
26 dept0_.id=?
27 Staff [id=4, name=qqq3, dept=oneToMany.Dept@1539b7a6]
 1         String hql = "from Staff where id = :id";
2 Query hqlQuery = session.createQuery(hql);
3
4 hqlQuery.setParameter("id", 4);
5
6 Staff staff = (Staff) hqlQuery.uniqueResult();
7 System.out.println(staff.toString());
8
9 //结果
10 Hibernate:
11 select
12 staff0_.id as id1_,
13 staff0_.name as name1_,
14 staff0_.deptId as deptId1_
15 from
16 staff staff0_
17 where
18 staff0_.id=?
19 Hibernate:
20 select
21 dept0_.id as id0_0_,
22 dept0_.name as name0_0_
23 from
24 dept dept0_
25 where
26 dept0_.id=?
27 Staff [id=4, name=qqq3, dept=oneToMany.Dept@1539b7a6]

                    注意,在位置上不仅仅可以插入值,还可以插入一个对象。例如

  String hql = "from Staff s where s.dept = ?";
2 Query hqlQuery = session.createQuery(hql);
3 Dept dept = (Dept)session.get(Dept.class, 2);
4 hqlQuery.setEntity(0, dept); //给相应位置添加一个dept对象
5 List list = hqlQuery.list();
6 System.out.println(list);
7
8 //结果
9 //这个是查询dept发送的sql语句
10 Hibernate:
11 select
12 dept0_.id as id0_0_,
13 dept0_.name as name0_0_
14 from
15 dept dept0_
16 where
17 dept0_.id=?
18 //这个是我们写的hql发送的sql语句
19 Hibernate:
20 select
21 staff0_.id as id1_,
22 staff0_.name as name1_,
23 staff0_.deptId as deptId1_
24 from
25 staff staff0_
26 where
27 staff0_.deptId=?
28 [Staff [id=2, name=qqq1], Staff [id=3, name=qqq2], Staff [id=4, name=qqq3], Staff [id=5, name=qqq4], Staff [id=6, name=qqq5], Staff [id=7, name=qqq6], Staff [id=8, name=qqq7], Staff [id=9, name=qqq8], Staff [id=10, name=qqq9]]
 1         String hql = "from Staff s where s.dept = ?";
2 Query hqlQuery = session.createQuery(hql);
3 Dept dept = (Dept)session.get(Dept.class, 2);
4 hqlQuery.setEntity(0, dept); //给相应位置添加一个dept对象
5 List list = hqlQuery.list();
6 System.out.println(list);
7
8 //结果
9 //这个是查询dept发送的sql语句
10 Hibernate:
11 select
12 dept0_.id as id0_0_,
13 dept0_.name as name0_0_
14 from
15 dept dept0_
16 where
17 dept0_.id=?
18 //这个是我们写的hql发送的sql语句
19 Hibernate:
20 select
21 staff0_.id as id1_,
22 staff0_.name as name1_,
23 staff0_.deptId as deptId1_
24 from
25 staff staff0_
26 where
27 staff0_.deptId=?
28 [Staff [id=2, name=qqq1], Staff [id=3, name=qqq2], Staff [id=4, name=qqq3], Staff [id=5, name=qqq4], Staff [id=6, name=qqq5], Staff [id=7, name=qqq6], Staff [id=8, name=qqq7], Staff [id=9, name=qqq8], Staff [id=10, name=qqq9]]

                    这两种方式度可以,不过在参数比较多的情况下,建议使用别名,那样更加清楚,不易出错,在少量参数时可以使用索引。

  

      1.4、QBC检索方式

          QBC:Query By Criteria,是一种更加面向对象的查询语言,提供的一系列QBC API来检索对象。

          HQL所能做的事情,使用QBC也大多能做用,这个通过实例来看看QBC是如何使用的。  

           步骤:

             1>获得session

             2>session.createCriteria(Obejct.class); 创建criteria对象

             3>使用criteria的API方法进行条件的增加。add(Restrictions.eq(属性名,值))

             4>执行查询

                  list():返回一个集合列表,有可能集合中装的是数组,有可能是POJO对象。

                  uniqueResult():返回一个查询结果,在已知查询结果只有一个或者0个时,使用是没有问题的,如果返回结果有多个,那么就会报异常

          例子一:使用QBC来对Staff进行查询

 1         //使用QBC,更加面向对象,不用写sql语句。要查询什么,就直接将其类.class当作参数就能查询出来
2 Criteria QBCCriteria = session.createCriteria(Staff.class);
3 List<Staff> staffList = QBCCriteria.list();
4 for(Staff staff : staffList){
5 System.out.println(staff.toString());
6 }
7 //结果
8 Hibernate:
9 select
10 this_.id as id1_0_,
11 this_.name as name1_0_,
12 this_.deptId as deptId1_0_
13 from
14 staff this_
15 Staff [id=2, name=qqq1]
16 Staff [id=3, name=qqq2]
17 Staff [id=4, name=qqq3]
18 Staff [id=5, name=qqq4]
19 Staff [id=6, name=qqq5]
20 Staff [id=7, name=qqq6]
21 Staff [id=8, name=qqq7]
22 Staff [id=9, name=qqq8]
23 Staff [id=10, name=qqq9]
 1         //使用QBC,更加面向对象,不用写sql语句。要查询什么,就直接将其类.class当作参数就能查询出来
2 Criteria QBCCriteria = session.createCriteria(Staff.class);
3 List<Staff> staffList = QBCCriteria.list();
4 for(Staff staff : staffList){
5 System.out.println(staff.toString());
6 }
7 //结果
8 Hibernate:
9 select
10 this_.id as id1_0_,
11 this_.name as name1_0_,
12 this_.deptId as deptId1_0_
13 from
14 staff this_
15 Staff [id=2, name=qqq1]
16 Staff [id=3, name=qqq2]
17 Staff [id=4, name=qqq3]
18 Staff [id=5, name=qqq4]
19 Staff [id=6, name=qqq5]
20 Staff [id=7, name=qqq6]
21 Staff [id=8, name=qqq7]
22 Staff [id=9, name=qqq8]
23 Staff [id=10, name=qqq9]

          例子二:使用QBC来对Staff进行条件查询

        //使用QBC,对Staff进行查询
2 Criteria QBCCriteria = session.createCriteria(Staff.class);
3 //add()添加条件,通过Restrictions(字段名,值),由于确定是1行记录,所以直接用uniqueResult()
4 Staff staff = (Staff) QBCCriteria.add(Restrictions.eq("id",3)).uniqueResult();
5
6 System.out.println(staff.toString());
7
8 //结果
9 Hibernate:
10 select
11 this_.id as id1_0_,
12 this_.name as name1_0_,
13 this_.deptId as deptId1_0_
14 from
15 staff this_
16 where
17 this_.id=?
18 Staff [id=3, name=qqq2]
 1         //使用QBC,对Staff进行查询
2 Criteria QBCCriteria = session.createCriteria(Staff.class);
3 //add()添加条件,通过Restrictions(字段名,值),由于确定是1行记录,所以直接用uniqueResult()
4 Staff staff = (Staff) QBCCriteria.add(Restrictions.eq("id",3)).uniqueResult();
5
6 System.out.println(staff.toString());
7
8 //结果
9 Hibernate:
10 select
11 this_.id as id1_0_,
12 this_.name as name1_0_,
13 this_.deptId as deptId1_0_
14 from
15 staff this_
16 where
17 this_.id=?
18 Staff [id=3, name=qqq2]

          例子三:QBC也能进行连接查询

        // from Staff inner join dept d ON 后面是hibernate自动帮我们填写;
2 Criteria criteria = session.createCriteria(Staff.class);
3 //createAlias默认是内连接,可以不用写。可以为dept表取别名,也可以不取。
4 criteria.createAlias("dept", "d", Criteria.INNER_JOIN);
5 List list = criteria.list();
6 System.out.println(list);
7
8 //结果
9 Hibernate:
10 select
11 this_.id as id1_1_,
12 this_.name as name1_1_,
13 this_.deptId as deptId1_1_,
14 d1_.id as id0_0_,
15 d1_.name as name0_0_
16 from
17 staff this_
18 inner join
19 dept d1_
20 on this_.deptId=d1_.id
21 [oneToMany.Staff@6a155d66, oneToMany.Staff@55a7e5ae, oneToMany.Staff@1d82e71, oneToMany.Staff@17d0fda9, oneToMany.Staff@19bd6e76, oneToMany.Staff@639f122d, oneToMany.Staff@60627b73, oneToMany.Staff@6196ec74, oneToMany.Staff@7b7de5b9]
 1         // from Staff inner join dept d ON 后面是hibernate自动帮我们填写;
2 Criteria criteria = session.createCriteria(Staff.class);
3 //createAlias默认是内连接,可以不用写。可以为dept表取别名,也可以不取。
4 criteria.createAlias("dept", "d", Criteria.INNER_JOIN);
5 List list = criteria.list();
6 System.out.println(list);
7
8 //结果
9 Hibernate:
10 select
11 this_.id as id1_1_,
12 this_.name as name1_1_,
13 this_.deptId as deptId1_1_,
14 d1_.id as id0_0_,
15 d1_.name as name0_0_
16 from
17 staff this_
18 inner join
19 dept d1_
20 on this_.deptId=d1_.id
21 [oneToMany.Staff@6a155d66, oneToMany.Staff@55a7e5ae, oneToMany.Staff@1d82e71, oneToMany.Staff@17d0fda9, oneToMany.Staff@19bd6e76, oneToMany.Staff@639f122d, oneToMany.Staff@60627b73, oneToMany.Staff@6196ec74, oneToMany.Staff@7b7de5b9]

          给一张表来看看qbc增加的条件查询语句。

                

          重点有一个离线Criteria对象的用法。

            1、在web层封装查询条件到离线Criteria对象中,将其DetachedCriteria对象绑定到Thread上。

            2、到dao层,就能通过Thread拿到该离线Criteria对象,然后创建session。将session给DetachedCriteria,就能够执行查询

            代码:

             WEB层

              DetachedCriteria detachedCriteria =DetachedCriteria.forClass(Customer.class);

              detachedCriteria.add(Restrictions.eq("name", "kitty"));

             DAO层

              Session session = HibernateUtils.openSession();

                  Transaction transaction = session.beginTransaction();

                // 将离线查询对象 关联到Session

               Criteria criteria = detachedCriteria.getExecutableCriteria(session);

               Customer customer = (Customer) criteria.uniqueResult();

                

    

      1.5、本地SQL检索方式

          使用标准的SQL语句来编写。

          步骤:

            1>获得session

            2>编写sql语句

            3>session.createSQLQuery(sql);获取SQLQuey对象

            4>给sql语句设置参数。

            5>执行查询

                  list():返回一个集合列表,集合中装的是Object[]。

                  返回实体类对象集合,如果与实体类进行了绑定,也就是使用了addEntity(xxx.class)。

          例子一:查询Staff的所有记录

     //使用的就是数据库表名了。
2 SQLQuery SQLquery = session.createSQLQuery("select * from staff");
3 //返回的是一个List<Object[]> 其中如果使用的SQL的话,
4 //后面不能够通过获得数组然后在转换为对象。只有通过addEntity。来绑定实体。
5 List list = SQLquery.list();
6 System.out.println(list);
7
8 //结果
9 Hibernate:
10 select
11 *
12 from
13 staff
14 [[Ljava.lang.Object;@2c8938a8, [Ljava.lang.Object;@64e6b46f, [Ljava.lang.Object;@66501729, [Ljava.lang.Object;@1420b939, [Ljava.lang.Object;@70605781, [Ljava.lang.Object;@45110fca, [Ljava.lang.Object;@6323ba32, [Ljava.lang.Object;@3e955b77, [Ljava.lang.Object;@3fa801ba]
 1         //使用的就是数据库表名了。
2 SQLQuery SQLquery = session.createSQLQuery("select * from staff");
3 //返回的是一个List<Object[]> 其中如果使用的SQL的话,
4 //后面不能够通过获得数组然后在转换为对象。只有通过addEntity。来绑定实体。
5 List list = SQLquery.list();
6 System.out.println(list);
7
8 //结果
9 Hibernate:
10 select
11 *
12 from
13 staff
14 [[Ljava.lang.Object;@2c8938a8, [Ljava.lang.Object;@64e6b46f, [Ljava.lang.Object;@66501729, [Ljava.lang.Object;@1420b939, [Ljava.lang.Object;@70605781, [Ljava.lang.Object;@45110fca, [Ljava.lang.Object;@6323ba32, [Ljava.lang.Object;@3e955b77, [Ljava.lang.Object;@3fa801ba]

          例子二:查询Staff的所有记录,并且绑定实体。 addEntity。

 1         //使用的就是数据库表名了。
2 SQLQuery SQLquery = session.createSQLQuery("select * from staff");
3 //返回的是一个List<Object[]> 只有通过addEntity。来绑定实体。
4 List<Staff> list = SQLquery.addEntity(Staff.class).list();
5 System.out.println(list.get(0).getName());
6
7 //结果
8 Hibernate:
9 select
10 *
11 from
12 staff
13 qqq1
 1         //使用的就是数据库表名了。
2 SQLQuery SQLquery = session.createSQLQuery("select * from staff");
3 //返回的是一个List<Object[]> 只有通过addEntity。来绑定实体。
4 List<Staff> list = SQLquery.addEntity(Staff.class).list();
5 System.out.println(list.get(0).getName());
6
7 //结果
8 Hibernate:
9 select
10 *
11 from
12 staff
13 qqq1

二、总结

      以上就是我们说的5种检索,其中说的重点就是hql的用法,上面的例子全部写完了差不多就对hql有一定的了解。记住hql是对pojo类进行操作,而不是对数据库中的表。在使用连接查询时,可以使用QBC,因为更简单,只需要用createAlias()就能使用任何的连接。一般在开发中sql语句都会提取出来放到hbm中,例如

      

        在hbm映射文件 (也可以用注解配置)

             <!-- 这里可以定义命名查询 -->

           <!--        定义 HQL 语句 <query name=""></query> -->

          <!--        定义 SQL 语句 <sql-query name=""></sql-query> -->

            <query name="findCustomerByName">

          <![CDATA[from Customer where name = ?]]>

          </query>

            * 为hql语句 起了一个名字

        程序代码:

            //相当于把sql语句分离开来了。方便维护

            Query query = session.getNamedQuery("findCustomerByName");

             query.setParameter(0, "tom");

          Customer customer = (Customer) query.uniqueResult();

Hibernate学习(七)———— hibernate中查询方式详解的更多相关文章

  1. hibernate(七) hibernate中查询方式详解

    序言 之前对hibernate中的查询总是搞混淆,不明白里面具体有哪些东西.就是因为缺少总结.在看这篇文章之前,你应该知道的是数据库的一些查询操作,多表查询等,如果不明白,可以先去看一下 MySQL数 ...

  2. Hibernate学习(3)- *.hbm.xml详解

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBL ...

  3. hibernate学习(4)——实体配置详解

    1.实体 编写规则 提供一个无参数 public访问控制符的构造器 提供一个标识属性,映射数据表主键字段,hibernate以id识别,必须有主键 所有属性提供public访问控制符的 set  ge ...

  4. Java Web学习(三)数据加密方式详解

    一.对称加密 定义:加密和解密使用相同密钥的算法. 常见的有DES.3DES.AES.PBE等加密算法,这几种算法安全性依次是逐渐增强的. DES加密 特点:简便.密钥长度比较短. import ja ...

  5. java学习(二)多态中成员变量详解

    今天我总结了一下java多态中成员变量的赋值与调用 举一个我当初做过的小案例: class Fu{ int num; void show(){} } class Zi extends Fu{ //in ...

  6. div学习之div中dl-dt-dd的详解

    dl dt dd认识及dl dt dd使用方法 <dl> 标签用于定义列表类型标签. dl dt dd目录 dl dt dd介绍 结构语法 dl dt dd案例 dl dt dd总结 一. ...

  7. JAVA中的四种JSON解析方式详解

    JAVA中的四种JSON解析方式详解 我们在日常开发中少不了和JSON数据打交道,那么我们来看看JAVA中常用的JSON解析方式. 1.JSON官方 脱离框架使用 2.GSON 3.FastJSON ...

  8. Spring事务Transaction配置的五种注入方式详解

    Spring事务Transaction配置的五种注入方式详解 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学 ...

  9. oracle中imp命令详解 .

    转自http://www.cnblogs.com/songdavid/articles/2435439.html oracle中imp命令详解 Oracle的导入实用程序(Import utility ...

随机推荐

  1. RK3288 uboot启动流程

    VS-RK3288嵌入式板卡 U-boot 启动流程小结 bl    board_init_f -> crt0.S    initcall_run_list(init_sequence_f) - ...

  2. CodeSampler DX9 Full-screen initialization

    D3D新手,请轻拍. 最近在学CodeSampler上的DX9范例.编译环境是VS2012.搭编译环境用了一两天,另行开文吐槽(有时间的话). 本文讲讲Full-screen initializati ...

  3. rest_framework登录组件,权限组件

    昨日回顾: -HyperlinkedIdentityField(用来生成url),传三个参数 -实例化序列化类的时候,BookSerializer(ret, many=True, context={' ...

  4. C语言常识

    struct tree{ struct tree *left; struct tree *right; }; typedef struct tree newtree; int main(int arg ...

  5. 项目小程序笔记-登录界面+FPGA管脚分配文件生成

    声明:只是为了记录我遇到的一些问题,其中有我理解错的望勿参考. (1)qt designer设计好窗口 主窗口: 登录窗口: 关于qt designer的使用,大可以百度,很简单的,要注意的是部件的参 ...

  6. hadoop配置笔记

    接上回,hadoop的配置文件都在下载的压缩包目录中的etc/hadoop/中 hadoop-env.sh有个地方配置java_home 其他常用的设置文件有: core-site.xml yarn- ...

  7. 背水一战 Windows 10 (94) - 选取器: 自定义文件打开选取器

    [源码下载] 背水一战 Windows 10 (94) - 选取器: 自定义文件打开选取器 作者:webabcd 介绍背水一战 Windows 10 之 选取器 自定义文件打开选取器 示例1.演示如何 ...

  8. 【react】利用shouldComponentUpdate钩子函数优化react性能以及引入immutable库的必要性

    凡是参阅过react官方英文文档的童鞋大体上都能知道对于一个组件来说,其state的改变(调用this.setState()方法)以及从父组件接受的props发生变化时,会导致组件重渲染,正所谓&qu ...

  9. Gephi安装过程中出现错误:can’t find java 1.8 or higher

    Gephi具体的安装过程我就不多说了,一直点击下一步就OK了,我想说的是出现如下图这种或者类似的错误怎么解决. 在百度的过程中发现很多的博文等等出现这个错误的解决方法都是安装对应版本的JDK啊,配置对 ...

  10. 18年最有"钱"途的专业就是它(文末有福利)

    根据社会调查机构麦可思发布的<2018年中国大学生就业报告>中得知,从就业率.薪资和就业满意度等多角度综合考量,信息安全专业为首推绿牌专业. 不管你是计算机相关专业的学生,还是已经工作的I ...