Hibernate框架进阶(下篇)之查询

导读

Hibernate进阶篇分为上中下三篇,本文为最后一篇,主要内容是Hibernate框架的查询,主要包括hql语句查询,criteria查询以及查询策略的选择。

知识框架

Hibernate查询
一、查询方式:hql语言、criteria接口和sql语言。
    hql语言和criteria都是面向对象的查询方式,但最终都是要转换为sql语言执行的。
1、hql语言
    1)简单查询
    2)条件查询
    3)排序查询
    4)分页查询
    5)统计查询
    6)投影查询
2、criteria
    1)简单查询
    2)条件查询
    3)排序查询
    4)分页查询
    5)统计查询
    6)离线查询
二、查询策略
    Hibernate查询策略主要是查询是两方面的选择:1、是否延迟加载sql查询语句;2、选择何种查询:单表、多表还是子查询。
1、类级别查询策略
    类级别延迟加载
2、关联级别查询策略(了解)
三、扩展:多表查询
1、交叉连接
2、内连接
3、外连接

一、查询方式

Hibernate支持三种查询方式:HQL(Hibernate Query Language)、Criteria接口和SQL。其中HQL和Criteria都是面向对象的查询,但最终都要装换为sql查询语句才执行。

1、HQL

为了方便说明,假设有表person和对应的实体类Person,且放于包domain下。

1)简单查询

sql语句:select * from person

hql语句:select * from domain.Person

注:select * 可以省略;如果整个项目下只有一个Person类,那么包名domain也可以省略。  

2)条件查询

sql语句:select * from person where pid = ?

sql设置占位符:PreparedStatement.setInt(0,pid);

(方式1)

hql语句:select * from domain.Person where pid = ?

hql设置占位符:session.setParameter(0,pid);

(方式2)

hql语句:select * from domain.Person where pid = :myPid

hql设置占位符:session.setParameter("myPid",pid);

3)排序查询

升序

sql语句:select * from person order by age asc

hql语句:select * from domain.Person order by age asc

降序

sql语句:select * from person order by age desc

hql语句:select * from domain.Person order by age desc

 

4)分页查询

sql语句:select * from person limit ?,?

hql语句:select * from domain.Person limit ?,?

hql分页占位符:session.setFirstResult(first);

        session.setMaxResults(max);

注:first代表分页的第一条数据,max代表分页的总条数。

5)统计查询

sql语句:select count(*)  from person

hql语句:select count(*)  from domain.Person

注:常用的聚合函数包括: count(字段)、 sum(字段)、 avg(字段)、 min(字段)、 max(字段)。

6)投影查询

投影查询其实就是查询需要的字段或字段组合。如只查询person表的age字段

sql语句:select age from person

hql语句:select age  from domain.Person

2、Criteria

criteria接口时完全面向对象的查询方式,不再像hql一样还需要书写语句,而是完全地通过调用方法来进行查询操作。

常用对象:

1)Criteria接口

2)查询执行对象Restrictions对象。提供了很多静态方法以供查询使用:

1)简单查询

1 //获得criteria
2 Criteria criteria = session.createCriteria(Person.class);
3 //获得结果集
4 List<Person> list = criteria.list();

2)条件查询

1 //获得criteria
2 Criteria criteria = session.createCriteria(Person.class);
3 
4 //添加查询条件
5 SimpleExpression eq = Restrictions.eq("name", "张三");
6 criteria.add(eq);//查询name="张三"的记录
7 
8 //获得结果集
9 List<Person> list = criteria.list();

相关的查询方法看上文的表格。

3)排序查询

1 //获得criteria
2 Criteria criteria = session.createCriteria(Person.class);
3 
4 //添加排序条件
5 Order asc = Order.asc("age");//按年龄升序排序
6 criteria.addOrder(asc);
7 
8 //获得结果集
9 List<Person> list = criteria.list();

4)分页查询

1 //获得criteria
2 Criteria criteria = session.createCriteria(Person.class);
3 
4 //添加分页条件
5 criteria.setFirstResult(0);
6 criteria.setMaxResults(5);
7 
8 //获得结果集
9 List<Person> list = criteria.list();

5)统计查询

1 //获得criteria
2 Criteria criteria = session.createCriteria(Person.class);
3 
4 //添加统计条件
5 criteria.setProjection(Projections.rowCount());//查询总记录数
6 
7 //获得结果
8 Long count = (Long)criteria.uniqueResult();

6)离线查询

 我们上面使用的criteria对象是由session创建的,所以要使用criteria对象必须先有session对象。但是DetachedCriteria对象(离线条件查询对象)可以直接创建而不通过session,且也能调用上面的查询语句,唯一不同之处在于DetachedCriteria是没有与session对象绑定的,所以称为离线查询对象。

DetachedCriteria对象的出现主要是运用在java的三层架构上,比如当web层需要传递很多参数作为查询条件时,将参数传到service层再传给dao层是十分麻烦的。我们可以在web直接使用DetachedCriteria离线查询,然后只传递这个对象给dao层即可。

需要注意的两个api:

DetachedCriteria对象的创建:

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

 DetachedCriteria对象与session绑定:(离线查询绑定之后就能持久化到数据库了)

detachedCriteria.getExecutableCriteria(session);

二、查询策略  

 Hibernate查询策略主要是查询是两方面的选择:1、是否延迟加载sql查询语句;2、选择何种查询:单表、多表还是子查询。

1、类级别查询策略  

 类级别查询策略主要是延迟加载策略,延迟加载就是当session从数据库加载对象是先不调用sql查询语句,直到该对象使用时再加载。延迟加载最大化地优化了查询,及不使用就不必执行查询了。

如何使用:1)在配置文件中的class元素中配置属性:lazy=true(false表示不延迟加载)。当然,默认就是true,所以如果使用延迟加载就忽略这个配置。

     2)使用upload()方法代替get()方法读取对象。(get方法不支持延迟加载策略)

问题:延迟加载是在对象与session绑定是才生效,所以一旦session.close之后再操作对象就会发生异常。

2、关联级别查询策略

关联级别即多表关系中,在关联属性下的属性配置:

其实关联级别的默认属性就是性能最优状态了,感兴趣的可以手动配置上面的信息进行性能比较。

问题:但是要注意的一个问题就是上面说到的延迟加载问题,一旦session关闭就不能再获取加载的对象了,这个问题主要发生在Java三层架构中,当页面需要获得数据库的某条记录时,我们使用到了延迟加载,而当返回页面时显然session对象已经关闭,这是页面就无法获得该对象(该记录)。如何保证在页面使用到该对象时session处于绑定(未关闭)状态呢?

解决:使用filter过滤器可以扩展session的作用范围:即在filter初始化时就打开session,然后放行,在页面加载结束后再关闭session即可。

三、扩展:多表查询

多表查询分为:交叉连接(笛卡尔积);内连接;外连接。

1、交叉连接

即两个表笛卡尔积组合表,一般我们避免使用。

2、内连接

1)隐示内连接

sql语句:select * from A a,B b where b.aid = a.id

2)显示内连接

sql语句:select * from A a inner join B b on b.aid = a.id

3、外连接

1)左外连接

sql语句:select * from A a left [outer] join B on b.aid=a.id;

2)右外连接

sql语句:select * from A a right [outer] join B on b.aid=a.id;

(这里的outer可以省略)

看图:

HIbernate框架的进阶内容就总结到这里,大吉大利,今晚吃鸡!

 

posted @ 2017-12-16 17:54  风之之  阅读(457)  评论(0编辑  收藏  举报