Hibernate(一) 之 延迟加载

来源:互联网 发布:js校验身份证号 编辑:程序博客网 时间:2024/04/30 11:02
       Hibernate延迟加载,又叫懒加载。 延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。在Hibernate中提供了 对实体对象的延迟加载以及对集合的延迟加载,另外在Hibernate3中还提供了对属性的延迟加载。
        在Hibernate中我们知道如果要从数据库中得到一个对象,通常有两种方式,一种是通过session.get()方法,另一种就是通过session.load()方法,然后其实这两种方法在获得一个实体对象时是有区别的,在查询性能上两者是不同的。
        当使用load方法来得到一个对象时,此时Hibernate会使用延迟加载的机制来加载这个对象,即:当 我们使用session.load()方法来加载一个对象时,此时并不会发出sql语句,当前得到的这个对象其实是一个代理对象,这个代理对象只保存了实 体对象的id值,只有当我们要使用这个对象,得到其它属性时,这个时候才会发出sql语句,从数据库中去查询我们的对象。
           session = HibernateUtil.openSession();
           User user = (User)session.load(User.class, 2);
           System.out.println(user);
        相对于load的延迟加载方式,get就直接的多,当我们使用session.get()方法来得到一个对象时,不管我们使不使用这个对象,此时都会发出sql语句去从数据库中查询出来。
            session = HibernateUtil.openSession();
            /*
             * 通过get方法来加载对象时,不管使不使用该对象,都会发出sql语句,从数据库中查询
             */
            User user = (User)session.get(User.class, 2);
当了解了load和get的加载机制以后,我们此时来看看这两种方式会出现的一些小问题:
    1、如果使用get方式来加载对象,当我们试图得到一个id不存在的对象时,此时会报NullPointException的异常。这是因为通过get方式我们会去数据库中查询出该对象,但是这个id值不存在,所以此时user对象是null,所以就会报NullPointException的异常了。
    2、如果使用load方式来加载对象,当我们试图得到一个id不存在的对象时,此时会报ObjectNotFoundException异常。
为 什么使用load的方式和get的方式来得到一个不存在的对象报的异常不同呢?其原因还是因为load的延迟加载机制,使用load时,此时的 user对象是一个代理对象,仅仅保存了当前的这个id值,当我们试图得到该对象的username属性时,这个属性其实是不存在的,所以就会报出 ObjectNotFoundException这个异常了。
    3、org.Hibernate.LazyInitializationException异常
这个异常是什么原因呢?还是因为load的延迟加载机制,Lazy只有在session打开的时候才有效,session关闭后lazy就没效了。当我们通过load()方法来加载一个对象时,此时并没有发出sql语句去从数据库中查 询出该对象,当前这个对象仅仅是一个只有id的代理对象,我们还并没有使用该对象,但是此时我们的session已经关闭了,所以当我们在测试用例中使用 该对象时就会报LazyInitializationException这个异常了。
        所以当我们看到控制台报LazyInitializationException异常,就知道是使用了load的方式延迟加载一个对象了,解决这个的方法有两种,一种是将load改成get的方式来得到该对象,另一种是在表示层来开启我们的session和关闭session,延长session的有效期。
        Hibernate 的延迟加载(lazy load)是一个被广泛使用的技术。这种延迟加载保证了应用只有在需要时才去数据库中抓取相应的记录。通过延迟加载技术可以避免过多、过早地加载数据表里 的数据,从而降低应用的内存开销。Hibernate 的延迟加载本质上就是代理模式的应用,当程序通过 Hibernate 装载一个实体时,默认情况下,Hibernate 并不会立即抓取它的集合属性、关联实体所以对应的记录,而是通过生成一个代理来表示这些集合属性、关联实体,这就是代理模式应用带来的优势。
        Hibernate 中主要通过代理(proxy)机制来实现延迟加载的。具体过 程:Hibernate从数据库获取某一个对象数据时、获取某一个对象的集合属性值时,或获取某一个对象所关联的另一对象时,由于没有使用该对象的数据 (除标识符值外),Hibernate并不从数据库加载真正的数据,而只是为该对象创建一个代理对象来代表这个对象,这个对象上的所有属性都为默认值;只 有在真正需要使用该对象的数据时才创建这个真实对象,真正从数据库中加载它的数据。这样在某些情况下,就可以提高查询效率。


0 0
原创粉丝点击