检索即对象的获取:获取的时机和和方式:减少没必要的内存占用,尽量少的sql语句减少多余数据库的访问
一:类级别的检索:load() 和属性<class lazy=true>
1.无论 <class> 元素的 lazy 属性是 true 还是 false, Session 的 get() 方法及 Query 的 list() 方法在类级别总是使用立即检索策略;仅对load()有效
2.默认是延迟加载的即lazy=true;当使用对象属性的时候才真正获取对象(前提是load());
3.根据是获取引用还是属性,是否使用延迟加载;
4.实现延迟加载的原理是使用cglib代理,根据id获取对象时,返回的代理对象只对oid初始化,使用到其他属性才进行初始化代理实例。
二。一:关联对象(一对多和多对多的情况)的检索;<set >元素的 lazy, batch-size fetch 属性值
<set >元素的 lazy属性
1.默认是懒加载关联的集合对象 默认set元素的lazy=true;在使用集合元素并且集合的iterator(), size(), isEmpty(), contains() 等方法也会初始化代理对象。
2在延迟加载的情况下,也可显示的初始化:通过 Hibernate.initialize() 静态方法
3..值可以是lazy=extra :即增强的延迟加载;尽可能延迟加载,如果只是集合的iterator(), size(), isEmpty(), contains() 等方法,只会用特殊的查询语句不会查询具体的数据;(一般不用,因为要得到数据最终还是需要发送语句去查询具体数据)
4.一般不设置为false:有时候并不需要关联对象;在使用一条语句获取第一个对象时,同时再使用一条语句获取关联的对象集合;
<set> 元素 batch-size 属性:用来为延迟检索策略或立即检索策略设定批量检索的数量. 批量检索能减少 SELECT 语句的数目,
一般情况下:
在获取每个客户对应的订单集合对象时,一个客户发送一条语句查询数据;
而通过设置batch-size="数量",让同一种方式获取同一类的对象用in语句(from order where customerId in(客户Id ,..))查询出来,设置的数量决定语句in的客户id数量;
查询语句的数量由总数量和每次查询的数量(batch-size)决定;
<set> 元素的 fetch 属性: 取值为 “select” 或 “subselect” 时, 决定初始化 orders 的查询语句的形式(相当于最大的batch-size值); join值决定加载的时机和方式;
1.默认是select 即普通查询:需参考其他属性;
2.值为subselect时,将忽略batch-size属性,但lazy属性有效;通过一条语句给所有客户关联的集合初始化;因为通过子查询将所有的客户id查出来作为外部语句in的元素(where customerid in(子查询客户id);(注意上面所说的所有(的客户id),只是上条语句查询到session中的客户对象)
3.为 “join” 时:在非Query 的list() 方法获取对象时;将忽略lazy属性(当然batch-size属性此时忽略不忽略没有意义因为它是对于多个对象获取其关联的集合):检索 Customer 对象时, 会采用迫切左外连接(通过左外连接加载的方式使用一条语句把客户和订单数据都获取到)策略来检索所有关联的 Order 对象
二。二(多对一和一对一》many-to-one ><one-to-one>的lazy属性;
lazy属性:
1.lazy默认是proxy:延迟加载
2.lazy为false:立即检索,执行两条语句,一条查询订单,一条查询客户,而查询客户对象时,受到客户对象的配置影响查询的方式不一样(因为是否需要查询出客户中引用的订单)
属性fetch=join:
1.即迫切左连接的方式;一次性将对象及关联对象初始化;
属性bathc-size 注意是<class>元素的属性
一般情况下:
查询每个订单关联的客户都有执行一条查询语句;
用batch-size的值设置数量;使用一条语句(in的方式)给多少个订单对应的客户对象初始化赋值;
总结:对多和对一相似意义的配置属性的位置是不同的;相同之处是list()获取时属性fetch=join将被忽略;
注意双向的一个问题:一个对象关联一个对象,而关联的对象本身也是关联的,是否是延迟加载的,将决定初始化关系对象的方式;
(是否所有的延迟加载的对象都是代理对象?)