hibernate延迟加载

本节内容:

  • l  掌握延迟策略概念
  • l  掌握实体对象的延迟加载
  • l  掌握集合类型的延迟加载
  • l  了解属性延迟加载

1  延迟策略概念

  •  延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。
  • 在Hibernate中提供了对实体对象的延迟加载以及对集合的延迟加载,另外在Hibernate3中还提供了对属性的延迟加载。
  • Hibernate中的延迟加载策略只有在session打开的状态下有效。

2  实体对象延迟加载

如果想对实体对象使用延迟加载,必须要在实体的映射配置文件中进行相应的配置,如下所示:

<!-- class的lazy属性设为true,则为实体的延迟加载 -->
    <class name="com.silvan.pojo.News" table="news" lazy="true">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <property name="title" />
        <property name="content" />
    </class>

插入数据后使用下面代码进行查询测试:

public void query(){
        Session session = HibernateUtil.getSession();
        Transaction tx = null;
        try{
            tx = session.beginTransaction();
            News news=(News)session.load(News.class,21);//(1)
            System.out.println(news.getTitle());//(2)
        }catch(Exception e){
            if(tx!=null){
                tx.rollback();
            }
            e.printStackTrace();
        }finally{
            HibernateUtil.closeSession(session);
        }
    }

解析:

  •  当运行到(1)处时,Hibernate并没有发起对数据的查询,如果我们此时通过一些调试工具,观察此时news对象的内存快照,我们会惊奇的发现,此时返回实体对象的代理类对象,这里所返回的对象类型就是News对象的代理类对象。
  •  当代码运行到(2)处时,此时调用news.getTitle() 方法,发出Sql语句进行查询。
  •  这样,通过一个中间代理对象,Hibernate实现了实体的延迟加载,只有当用户真正发起获得实体对象属性的动作时,才真正会发起数据库查询操作。所以实体的延迟加载是用通过中间代理类完成的,所以只有session.load()方法才会利用实体延迟加载,因为只有session.load()方法才会返回实体类的代理类对象。

3 集合类型的延迟加载

  • 在Hibernate的延迟加载机制中,针对集合类型的应用,意义是最为重大的,因为这有可能使性能得到大幅度的提高,我们在一对多关联中,定义用来容纳关联对象的Set集合,并不是java.util.Set类型或其子类型,而是net.sf.hibernate.collection.Set类型,通过使用自定义集合类的实现,Hibernate实现了集合类型的延迟加载。
  •  要求News类中写private Set editor;具体实现类让Hibernate赋予。

为了对集合类型使用延迟加载,我们必须如下配置集合的关联部分:

<!-- 集合的lazy属性设置为true,则为集合类型的延迟加载-->
<set name="editor" table="editor" lazy="true">
    <key column="id"></key>
    <element type="string" column="name"></element>
</set>

通过将<set>元素的lazy属性设置为true来开启集合类型的延迟加载特性。

我们看下面插入数据和查询的测试代码:

//插入
News news = new News();
news.setTitle("title");
news.setContent("content");
Set editor = new HashSet();
editor.add("qinqin1");
editor.add("qinqin2");
news.setEditor(editor);
session.save(news);

//查询
News news=(News)session.get(News.class,1);
//当集合lazy属性为true,只有在调用集合的时候才会执行集合查询语句,与使用get或load无关
    Set editor = news.getEditor();//(1)
    for(Object obj:editor){//(2)
        System.out.println(obj.toString());
    }

解析:

  当程序执行到(1)处时,这时并不会发起对关联数据的查询来加载关联数据,只有运行到(2)处时,真正的数据读取操作才会开始,这时Hibernate会根据缓存中符合条件的数据索引,来查找符合条件的实体对象。

4 属性的延迟加载

  • 在Hibernate3中,引入了一种新的特性——属性的延迟加载,这个机制又为获取高性能查询提供了有力的工具。在前面我们讲大数据对象读取时,在User对象中有一个resume字段,该字段是一个java.sql.Clob类型,包含了用户的简历信息,当我们加载该对象时,我们不得不每一次都要加载这个字段,而不论我们是否真的需要它,而且这种大数据对象的读取本身会带来很大的性能开销。
  • 在Hibernate3中,我们可以通过属性延迟加载机制,来使我们获得只有当我们真正需要操作这个字段时,才去读取这个字段数据。
  • 属性的延迟加载用的少,故了解
原文地址:https://www.cnblogs.com/zhouyeqin/p/7196130.html