Hibernate框架入门(四)

                                      第一章 查询-HQL语法

查询方式:oid查询-get、对象属性导航查询、HQL、Criteria、原生SQL

HQL基本检索

排序:

条件:

  分页:

从零条开始查,每页两条

统计:

count、sum、avg、max、min

如果是单个查询的话,建议不用list,用uniqueResult比较好,count的查询结果为Long型。

投影查询:投影只能投影一部分,其实也就是只查询属性中的一部分内容。

如:

 

多表查询:

回顾原生sql

交叉连接-笛卡儿积(避免)

select * from A,B

内连接(隐式内连接,显式内连接)

隐式:select * from A,B where b.ais=a.id

显式:select * from A inner join B on b.aid = a.ad

外连接左外,右外

左外:select * from A left [outer] join B on b.aid = a.id

右外:select * from B left[outer] join B on b.aid = a.id

HQL 的多表查询

内连接:下面的hql语句表示给customer起别名c,并自己连接自己的属性,最终会在内部转换熟悉的sql语句,将可以连接的进行连接,将连接的两端对象进行返回。

迫切内连接:迫切是封装后给你,将连接的对象装入customer的LinkMen的集合中。

外连接:

左外连接:

右外连接:

 

                                   第二章 查询-Criteria语法

无语句面对对象的查询

基本查询:

条件查询:

更多的条件见表:

分页查询:

排序:                      

统计:

离线查询:Criteria对象的创建依赖于session,在线的话就是用session将criteria创建,离线的话就是凭空将criteria创建,

在线:

 

离线:

 

                                      第三章 查询策略优化

3.1 类级别查询

懒加载|延迟加载

load方法:应用类级别的加载策略,可以在对象配置文件中进行配置,默认策略是延迟加载,是在执行时不发送任何sql语句,返回一个对象,使用该对象时,根据关联的session查询数据库,加载数据。

get方法不能配置,只有一种立即加载策略。

延迟加载:仅仅获得没有使用,不会查询。在使用时才进行查询。

是否对类进行延迟加载:可以通过在class元素上配置lazy属性来控制。

lazy:true 加载时 不查询,使用时才查询

lazy:false 加载时立即查询

在debug中看到代理对象的值出现$符号时,表明它是一个代理对象。可以让代理customer对象有查询数据库的功能,当需要使用时,便查询数据。

shi

以前在中文符号的问题那里进行过代理,转换过request,以便适应中文,在数据库中进行过代理,以实现连接池。

结论:为了提高效率,建议使用load加载即延迟加载策略。

注意:使用懒加载时要确保,调用属性加载数据时,session还是打开的,不然会抛出异常。

3.2 关联级别查询

关联级别延迟加载&抓取策略

3.21 集合关联策略

lazy属性:决定是否延迟加载 true:延迟加载, false:立即加载 extra:极其懒惰

fetch属性:决定加载策略。使用什么类型的sql语句加载集合数据

select:单表查询加载

join:使用多表查询加载集合

subselect:使用子查询加载集合

依次对这个属性进行排列组合,进行不同的测试。

为了叙述的方便,将下图中代码按照第一行,第二行,第三行等等进行描述。

(1) fetch:select     lazy:true   (默认值)

用单表查询,第一行执行时单表查询加载customer,第二行不查询linkmen,第三行需要用的时候再加载linkmen。

(2)  fetch:select     lazy:false

再第一行将所有数据全部加载。

(3) fetch:select     lazy:extra(极其懒惰)

第一行执行时单表查询加载customer,第二行不查询linkmen,第三行只查询行数,不加载linkmen,第三行需要用的时候再加载linkmen。

(4) fetch:join     lazy:true

因为是多表查询,所以在第一行即将所有的数据查完,lazy是什么也就失去了作用。

(4) fetch:subselect     lazy:true

只查询一个表时没机会用到子查询的,当如下情况会用到子查询。

第三行会查询所有customer,第五行正常输出,第六行会使用子查询,将所有的linkmen查出来。

(5) fetch:subselect     lazy:false

 

 

在三行会加载所有customer并利用子查询加载所有linkmen。

(6) fetch:subselect     lazy:true

第三行加载customer,第六行只查询size,第七行根据子查询查询所有linkmen。

3.22 关联属性策略

利用linkmen反过来加载customer

配置:

 

 

fetch:select     lazy:proxy     customer:true

第一行只会加载linkmen,因为懒加载,所以第三行使用时才加载customer。

fetch:select     lazy:proxy|false     customer:false

第一行会将linkmen以及它对应的customer全部加载

fetch:join     lazy:proxy

多表查询就是无论如何都会查出与linkmen关联的customer,所以lazy属性就无所谓了。

结论:为了提高效率,fetch的选择应为select,lazy的取值应选择true,即都是默认值。

no-session问题:当开启懒加载的时,若在web层中需要使用某对象的关联集合或者属性的话,因为在service层中已将session关闭,这里我们将不能找到需求的对象。

解决方法:扩大session的作用范围,可以使用过滤器来解决问题,

                              第四章:为客户列表增加查询操作

根据客户名称查询对象

web层:

如要在web层添加条件,应使用离线查询。

cust_name要加上百分号,不然变成了等于。

 

service层:

 

dao层:

 

将查询条件回显:

小疑问:session为什么不用打开了,之前说的no-session的问题为什么不会在这里在出现。