一,延迟加载    

    1、实体类延迟加载 通过代理机制完成,由javassist类库实现运行时代理,修改实体类的字节码实现了运行时代理
        <class lazy="true|false">
        实体级别的延迟加载默认值为true,意味实体对象是延迟加载,只影响load方法。
         <class lazy="true|false">其他查询方式都是立即加载
    
          2、关联属性延迟加载 默认情况下除了<one-to-one>之外所有的关联属性都是延迟加载
          A、单端关联对象<many-to-one lazy="proxy|no-proxy|false"> <one-to-one lazy="false|proxy|no-proxy">
             通过javassist代理实现延迟加载
     
          B、集合关联对象 <set lazy="true|extra|false">
             在hibernate中为实现集合关联属性的延迟加载,没有使用jdk中的集合框架,它实现了一套自己的集合框架,
              比如它的set集合通过PersistSet(该类实现java.util.Set接口)实现,
           集合关联属性的lazy默认值为true,意味集合关联属性延迟加载。
     
              lazy="extra"除指定集合属性延迟加载功能外,能够让hibernate智能感知开发者对关联的集合属性的操作类型,
               hibernate会根据开发者对集合操作类型不同执行不同的sql语句,所以建议集合关联属性的lazy="extra"         

          Department dept = (Department) session.get(Department.class, 10);

         Set<Employee> set = dept.getEmps();//获取到关联的集合属性

         //判断集合中元素个数是否为0 当关联属性lazy="true",如果我们仅仅需要判断集合中是否元素或者仅仅需要集合中元素个数不是这些元素
// select * from emp where deptno=?
boolean b = set.isEmpty();
//获取集合中元素的个数
int size = set.size();
         Department dept = (Department) session.get(Department.class, 10);

         Set<Employee> set = dept.getEmps();//获取到关联的集合属性

         //当lazy="extra"时,集合关联属性延迟加载,同时提供了一些功能,让hibernate能够智能感应开发者对集合关联属性的操作类型
//hibernate会根据开发者对集合属性的操作类型不同执行不同的sql语句
//当开发者执行调用集合属性的isEmpty()方法或者size()方法时发送select count(*) from emp where deptno=?
//当开发者执行遍历操作发送select * from emp where deptno=?
boolean b = set.isEmpty(); int size = set.size();

    3、普通属性延迟加载 编译时对字节码进行修改
        <property lazy="false|proxy|no-proxy">

  关联对象的延迟加载有利于程序的运行效率,但在一些情况下会产生问题,如:延迟加载的关联对象在session关闭后如何获取?

    1. openSessionInView,把session的生命周期延长,保证在获取关联对象后关闭session;
    2. 在HQL语句中使用关键字fetch左外连接查询,立即获取主体对象和关联对象          
List list=session.createQuery("from Employee e join fetch e.dept").list(); //Employee(dept)

     3. 在关联属性映射信息中将fetch="join",会通过左外连接立即把关联对象查询出来(不建议使用)

    4. 通过Hibernate工具类中initialize(Object lazyObject),立即加载关联对象 

    5. Criteria获取关联对象,调用setFetchMode("关联对象名",FetchMode m)将抓取方式m设置FetchMode.JOIN

    

 

二,抓取策略

  关联对象的抓取方式的设置:

      <many-to-one fetch="select|join">和<one-to-one fetch="join|select">

      <set fetch="select|join|subselect">

  join : 以左外连接形式立即获取关联对象(仅仅针对get方法和load方法时有效,对HQL查询、标准查询无效,不推荐设置)。
    select :另外发送一条查询语句获取关联对象
      subselect :另外发送一条查询语句或者子查询获取关联对象加载出来

  

三,1+n问题

    什么是1+N问题:当我们发送1条sql语句获取主体对象的数据,假设获取到n个主体对象,
               但是需要发送额外的n条数据获取关联对象。

    解决1+n问题:

             1、关联属性的映射文件信息中fetch="join",可以解决load和get方式的1+n问题(不建议)
             2、使用HQL语句中关键字fetch,通过左外连接立即加载关联对象,所以该操作前提,我们确实需要立即将关联对象加载
             3、使用Criteria查询语句,通过该对象的setFetchMode(String ass,FetchMode m) 设置为FetchMode.JOIN,
                 这样通过左外连接立即加载关联对象 只需要一条sql语句
             4、设置批量加载,减少查询语句

                    1、在hibernate.cfg.xml中配置<property name="default.batch_fetch_size">2</property>                                                    2、在集合关联属性<set batch-size="1|2|4|8|16">
                         单端的关联属性在单端对应的实体类<class batch-size="1|2|4|8|16">
             5、将<set fetch="subselect">获取关联集合属性时通过子查询获取,避免1+N问题。
             6、Query对象的iterator()方法引起的1+N问题要通过二级缓存解决

  

  

  

hibernate的延迟加载和抓取策略的更多相关文章

  1. 十、hibernate的延迟加载和抓取策略

    延迟加载:控制sql语句发送时机 抓取策略:控制sql语句格式,子查询.连接查询.普通sql 延迟加载 延迟加载(lazy),也叫做懒加载:执行到该行代码时,不发送sql进行查询,只有在真正使用到这个 ...

  2. hibernate 延迟加载和抓取策略

    一.延迟加载 1.简单查询get,load 针对对象本身延迟或即时 当使用load方法来得到一个对象时,此时hibernate会使用延迟加载的机制来加载这个对象,即:当我们使用session.load ...

  3. 【转】hibernate延迟加载和抓取策略

    一.延迟加载 1.简单查询get,load 针对对象本身延迟或即时 当使用load方法来得到一个对象时,此时hibernate会使用延迟加载的机制来加载这个对象,即:当我们使用session.load ...

  4. Hibernate fetching strategies(抓取策略)

    抓取策略(fetching strategies)是指:当应用程序需要在(Hibernate实体对象图的)关联关系间进行导航的时候,Hibernate如何获取关联对象的策略.抓取策略可以在O/R映射的 ...

  5. hibernate_06_hibernate的延迟加载和抓取策略

    1.延迟加载 1>类级别的延迟加载 指的是通过oad方法查询某个对象的时候,是否采用延迟, session. load(Customer class1L) 类级别延迟加载通过<class& ...

  6. Hibernate 性能优化之抓取策略

    fetch 抓取策略 前提条件:必须是一个对象操作其关联对象. 1. 根据一的一方加载多的一方,在一的一方集合中,有三个值:join/select/subselect 2.根据多的一方加载一的一方, ...

  7. Hibernate框架笔记04HQL_QBC查询详解_抓取策略优化机制

    目录 1. Hibernate的查询方式 1.1 方式一:OID查询 1.2 方式二:对象导航查询 1.3 方式三:HQL方式 1.4 方式四:QBC查询 1.5 方式五:SQL查询 2. 环境搭建 ...

  8. Hibernate之加载策略(延迟加载与即时加载)和抓取策略(fetch)

    假设现在有Book和Category两张表,表的关系为双向的一对多,表结构如下: 假设现在我想查询id为2的那本书的书名,使用session.get(...)方法: Session session=H ...

  9. 八 Hibernate延迟加载&抓取策略(优化)

    面试:Hibernate效率很低,如何优化? 缓存怎么弄的,语句怎么优化? 聊聊一级缓存,聊聊抓取策略和延迟加载,聊聊批量抓取 延迟加载: 一般不单独使用,和延迟加载一起使用 延迟加载:lazy(懒加 ...

随机推荐

  1. SourceTree跳过Atlassian账号,免登陆,跳过初始设置

    SourceTree 安装之后需要使用账号登陆以授权,并且是强制登陆. 登录过程非常漫长,并未在不FQ的情况下是不能成功的,下面记录一下跳过登录的方法. 装之后,转到用户本地文件夹下的 SourceT ...

  2. protocol buffers生成go代码原理

    本文描述了protocol buffers使用.proto文件生成pb.go文件的过程 编译器 编译器需要插件来编译环境,使用如下方式安装插件:go get github.com/golang/pro ...

  3. 高级网络功能(Docker支持的网络定制配置)

    网络的高级知识,包括网络的启动和配置参数.DNS的使用配置.容器访问和端口映射的相关实现. 在一些具体场景中,Docker支持的网络定制配置,通过Linux命令来调整.补充.甚至替换Docker默认的 ...

  4. iOS 微信支付SDK与微信友盟分享两者同时集成时,出现的问题与解决之路。

    这两天改版一个旧的APP,要旧貌换新颜,拿到app后进行编译,一直报下面的错误. 报不认识的符号名PayReq错误.奇怪,啥也没动就这样,真不知道给的包是不是本来就是个报错的工程. 不管怎样,要对它修 ...

  5. 通过spark-sql快速读取hive中的数据

    1 配置并启动 1.1 创建并配置hive-site.xml 在运行Spark SQL CLI中需要使用到Hive Metastore,故需要在Spark中添加其uris.具体方法是将HIVE_CON ...

  6. C#byte类型

    byte类型的范围是0~255转换为二进制是00000000~11111111 ---------------------------------------------------------- C ...

  7. JS中的拖动之—— ondragstart,ondrag,ondragend , ondragenter , ondragover , ondragleave, ondrop 的区别

    关于 HTML5 中的拖动功能. 更多信息可以查看我们 HTML 教程中的 HTML5 拖放.以下 我只做一下简介. 1 如果你想让元素变得可拖动,首先 你得对元素设置 draggable 属性 此属 ...

  8. [javaSE] 基本类型(String相关)

    字符串是一个特殊的对象 字符串一旦初始化就不可以被改变 获取字符串的长度 调用String对象的length()方法,返回int长度 获取某个索引位置的字符 调用String对象的charAt()方法 ...

  9. iOS字体打印

    //打印所以字体    NSArray *familyNames = [UIFont familyNames];    for(NSString *familyName in familyNames) ...

  10. 【原】公司P2P平台的功能拆分

    银行回调:由原来写在PC门户项目中拆分开来,作为一个专门处理回调的项目,配置多个数据源,实时写入数据库. 定时回查:由原来写在PC后台管理项目中拆分开来,作为一个专门回查银行网关的项目. 请求银行:由 ...