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的问题为什么不会在这里在出现。