延迟加载

Posted -EASY-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了延迟加载相关的知识,希望对你有一定的参考价值。

hibernate lazy策略可以使用在:
* <class>标签上,可以取值:true/false ,在hibernate3以上版本,默认是true
* <property>标签上,可以取值:true/false需要类增强工具
* <set><list>标签上,可以取值:true/false/extra
* <one-to-one><many-to-one>单端关联上,可以取值:false/proxy/no-proxy

lazy概念:只有真正使用该对象时,才会创建,对于hibernate而言,正真使用的时候才会发出sql

hibernate支持lazy策略只有在session打开状态下有效

1、在<class>标签上,可以取值:true/false ,在hibernate3以上版本,默认是true

     默认为true,可不写,在执行查询语句时不进行,比如session.load(id)时,不执行sql语句(session.get(id)不支持lazy),而是在具体获取参数时,执行sql语句,比如obj.getName()。

    <class>标签上的lazy特性只对普通属性起作用

    <class>标签上的lazy不会影响到单端关联上的lazy特性

2、<set><list>标签上,可以取值:true/false/extra
    lazy=true时,在获取对象的基本属性时,不进行set对象的查询,在获取set对象的具体属性时才进行查询,即在obj.getSet()不进行查询,obj.getSet().getName()时才进行查询

    lazy=false时,不延时,马上加载

    lazy=extra时,与=true时差不多(需要进一步验证

3、 <one-to-one><many-to-one>单端关联上,可以取值:false/proxy/no-proxy

    默认为lazy=proxy, 在获取关联对象时,不进行查询,在获取关联对象的具体实现时,才执行sql查询

    lazy=false时,不延时,马上加载

     many-to-one 的lazy设为proxy,当child.getParent().getName()或child.getParent().f()时,parent都会被抓取,若设为no-proxy,调用child.getParent().f()时,parent是不会被抓取的,同时这种方式需要编译时字节码增强,否则和proxy没区别。

."编译时字节码增强" 是什么意思? 
"字节码增强"分编译期和运行期2种,编译期是修改java类编译后的class字节码文件,在上面附加“增强”操作

lazy (可选 - 默认为 proxy): 默认情况下,单点关联是经过代理的。lazy="no-proxy"指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche lazily)(需要运行时字节码的增强)。 lazy="false"指定此关联总是被预先抓取。注意,如果constrained="false", 不可能使用代理,Hibernate会采取预先抓取!

 

lazy="proxy",也是延迟加载的一种,需要满足以下条件;

比如说User和Group是many-to-one的关系,User中有一个类型为Group的属性group,   
  若你想要载入一个User时,它的Group属性group要延迟载入,   
    
  条件一:   必须为Group类定义proxy,这个proxy一般可以定义为两种   
      1   Group类本身   
      2   一个被Group类实现的,且包含了Group类的所有业务方法的接口,这种做法可以克服第一种做法的一些缺点,但会比较麻烦,因为要定义一个接口嘛。   
    
  条件二:   映射文件中这个<many-to-one>的outer-join要定义为   
      1   "false"(如果你在hibernate.properties或hibernate.cfg.xml文件中定义了hibernate.use_outer_join   true)   
      2   "auto"(默认的)或"false"(hibernate.use_outer_join   false),(我没有试过当hibernate.use_outer_join   false时,<many-to-one>的outer-join定义为"true",会不会延迟载入和还是会用outer   join一并取出关联对象(在这里就是group对象),你可以试试)   
    
  hibernate中proxy是用cglib生成的动态代理,相关源码可以看看相应的原码。 

以上是关于延迟加载的主要内容,如果未能解决你的问题,请参考以下文章

hibernate延迟加载

延迟加载模块中的角度延迟加载模块

延迟加载

MyBatis一对多查询及延迟加载

MyBatis 延迟加载的三种加载方式深入,你get了吗?

mybatis探究之延迟加载和缓存