检索策略(抓取策略)

1.1. 延迟加载
延迟加载 是hibernate为提高程序执行的效率而提供的一种机制,即只有真正使用该对象的数据时才会创建。
load方法采用的策略延迟加载.
get方法采用的策略立即加载。
检索策略分为两种:
1. 类级别检索
2. 关联级别检索
1.2. 类级别检索
类级别检索是通过session直接检索某一类对应的数据,例如
Customer c=session.load(Customer.class,1)
Session.createQuery(“from Order”)
类级别检索策略分为立即检索与延迟检索,默认是延迟检索,类级别的检索策略可以通过<class>元素的lazy属性来设置 ,默认值是true
在hbm配置文件中设置
在类中使用注解
如果将lazy设置为false,代表类级别检索也使用立即检索。这时load与get就一样,都是立即检索。
如果对一个延迟代理对象进行初始化?
1.3. 关联级别检索
        查询到某个对象,获得其关联的对象或属性,这种称为关联级别检索,例如
        c.getOrders().size()
        c.getName()
        对于关联级别检索我们就要研究其检索策略(抓取策略)
1.4. 检索策略(抓取策略) 延迟加载
延迟加载 是hibernate为提高程序执行的效率而提供的一种机制,即只有真正使用该对象的数据时才会创建。
load方法采用的策略延迟加载.
get方法采用的策略立即加载。
检索策略分为两种:
3. 类级别检索
4. 关联级别检索
类级别检索
类级别检索是通过session直接检索某一类对应的数据,例如
Customer c=session.load(Customer.class,1)
Session.createQuery(“from Order”)
类级别检索策略分为立即检索与延迟检索,默认是延迟检索,类级别的检索策略可以通过<class>元素的lazy属性来设置 ,默认值是true
在hbm配置文件中设置
在类中使用注解
如果将lazy设置为false,代表类级别检索也使用立即检索。这时load与get就一样,都是立即检索。
如果对一个延迟代理对象进行初始化?
关联级别检索
        查询到某个对象,获得其关联的对象或属性,这种称为关联级别检索,例如
        c.getOrders().size()
        c.getName()
        对于关联级别检索我们就要研究其检索策略(抓取策略)
检索策略(抓取策略) 抓取策略介绍
指的是查找到某个对象后,通过这个对象去查询关联对象的信息时的一种策略。
一对一 <one-to-one>
一对多(多对一) <set>下有<one-to-many>  <many-to-one>
多对多 <set>下有<many-to- many>
我们主要是在<set>与<many-to-one>或<one-to-one>上设置fetch  lazy
例如:查询一个客户,要关联查询它的订单
客户是一的一方,在客户中有set集合来描述其订单,在配置中我们是使用
<set>
        <one-to-many>
</set>..
可以在set标签上设置两个属性  fetch   lazy
Fetch主要描述的是SQL语句的格式(例如是多条,子查询,多表联查
Lazy 控制SQL语句何时发送
例如:在查询一个订单时,要查询客户信息
<many-to-one> 或<one-to-one>
也可以设置fetch  lazy
Fetch主要描述的是SQL语句的格式(例如是多条,子查询,多表联查
Lazy 控制SQL语句何时发送
总结:
讲解抓取策略
在两方面设置
<set fetch=”” lazy=””>
<many-to-one fetch=”” lazy=””>
<one-to-one>
注解配置抓取策略
问题:如何使用注解来设置
在<setse>设置的fetch与lazy可以使用下面注解来描述
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps89F6.tmp.jpg
在<many-to-one>或<one-to-one>上如何设置 fetch与lazy
set上的fetch与lazy
set上的fetch与lazy它主要是用于设置关联的集合信息的抓取策略。
Fetch可取值有:
1. SELECT 多条简单的sql   (默认值)
2. JOIN 采用迫切左外连接
3. SUBSELECT 将生成子查询的SQL
lazy可取值有:
1. TURE 延迟检索   (默认值)
2. FALSE 立即检索
3. EXTRA 加强延迟检索(及其懒惰)
第一种组合
会首先查询客户信息,当需要订单信息时,才会关联查询订单信息。
第二种组合
s 
当查询客户信息时,就会将订单信息也查询,也就是说订单信息没有进行延迟。
第三种组合
当查询客户信息时,不会查询订单信息,当需要订单的个数时,也不会查询订单信息,
只会通过count来统计订单个数。
当我们使用size(),contains()或isEmpty()方法时不会查询订单信息。
第四种组合
如果fetch选择的是join方案,那么lazy它会失效。
生成SQl将采用的是迫切左外连接(left outer join fetch)
会立即查询。
第五种组合
会生成子查询,但是我们在查询订单时采用的是延迟加载。
第六种组合
会生成子查询,在查询客户信息时,就会将订单信息也查询出来
第七种组合
在查询订单时,只会根据情况来确定是否要订单信息,如果不需要,例如我们
程序中size操作,那么就会发出select count(*) from Order where c_customer_id=?
One的一言fetch与lazy
<set fetch lazy>它主要是设置在获取到一的一方时,如果去查询多的一方。
在<many-to-one>或<one-to-one>如果去查询对方。
对于程序 就是在多的一方如何查询一的主方信息
例如:获取到一个订单对象,要查询客户信息。
Fetch可取值:
        select 默认值,代表发送一条或多条简单的select语句
        join  发送一条迫切左外连接
lazy可取值
        false 不采用延迟加载
        proxy 默认值 是否采用延迟,需要另一方的类级别延迟策略来决定
        no-proxy 不用研究
第一种组合
注意:Customer的类级别延迟策略
当我们执行时,会首先发送一条sql只查询订单信息,客户信息会延迟,只有真正需要客户信息时,才会发送sql来查询客户信息.
第二种组合
注意:Customer的类级别延迟策略
当查询订单时,就会将客户信息也查询到,原因是Customer它的类级别延迟为false,也就是立即查询。
第三种组合
当查询订单时,不会对客户信息进行延迟,立即查询客户信息
第四种组合
如果fetch值为join,那么lazy失效。
会发送一条迫切左外连接来查询,也就立即查询。
1.5. 批量抓取
我们在查询多个对象的关联对象时,可以采用批量抓取方式来对程序进行优化.
要想实现批量抓取:
可以在配置文件中 batch-size属性来设置
可以使用注解 @BatchSize(size=4)
可以采用批量抓取来解决N+1问题.
查询客户,查询订单
可以在客户配置文件中配置batch-size,是在<set>标签上
查询订单,查询客户
订单与客户,客户它是一个主表,订单是一个从表。
在设置批量抓取时都是在主表中设置
在配置文件中在主表的<calss>标签上设置batch-size
在注解使用中
注意:无论是根据哪一方来查询别一方,在进行批量抓取时,都是在父方来设置 ,
        如果是要查询子信息,那么我们是在<set>上来设置batch-size,如果是从子方来查询父方,
        也是在父方设置在<class>设置batch-size.
        
父与子区分:
        有外键的表是子(从关联方就是父(主)表

猜你喜欢

转载自blog.csdn.net/qq_40208605/article/details/80745447
今日推荐