Hibernate中的延迟加载

属性的延迟加载

在Hibernate中,当使用load方式来得到一个对象,Hibernate会使用延迟加载的机制来加载这个对象。即:当我们使用session.load()方式来加载一个对象时,并不会发出sql语句,当前得到的对象只是一个代理对象,这个代理对象只保存了一个id值。只有当我们想要使用这个对象的其他属性时,才会发出sql语句,去数据库中查询。get方式没有属性的延迟加载。

        Product product=(Product) session.load(Product.class,20);
        System.out.println(product.getId());
        System.out.println(session.getStatistics().getEntityCount());
        System.out.println(product);
        System.out.println(session.getStatistics().getEntityCount());

控制台打印结果:

20
0
Hibernate: select product0_.id as id0_0_, product0_.name as name0_0_, product0_.price as price0_0_ from product_ product0_ where product0_.id=?
pojo.Product@3bb9a3ff
1

我们看到,执行完前两行代码后,session缓存中仍然没有对象,当执行到第4行代码后,才去数据库执行select操作,而且往session缓存中放入了一个对象。

 

由于

关系的延迟加载

在一对多,多对多的关系中都可以使用关系的延迟加载。Hibernate默认配置的是关系的延迟加载,即:lazy=true。

<hibernate-mapping package="pojo">
    <class name="Category" table="category_">
        <id name="id" column="id">
            <generator class="native">
            </generator>
        </id>
        <property name="name" />
        <set name="product" lazy="true">
            <key column="cid" not-null="false"/>
            <one-to-many class="Product"/>
        </set>
    </class>
</hibernate-mapping>
        Category category=(Category) session.get(Category.class,1);
        System.out.println(session.getStatistics().getEntityCount());
        System.out.println(category);
        System.out.println(session.getStatistics().getEntityCount());
        System.out.println(category.getProduct());
        System.out.println(session.getStatistics().getEntityCount());

控制台打印结果:

Hibernate: select category0_.id as id2_0_, category0_.name as name2_0_ from category_ category0_ where category0_.id=?
1
pojo.Category@72d1ad2e
1
Hibernate: select product0_.cid as cid2_1_, product0_.id as id1_, product0_.id as id0_0_, product0_.name as name0_0_, product0_.price as price0_0_ from product_ product0_ where product0_.cid=?
[pojo.Product@55183b20, pojo.Product@747ddf94, pojo.Product@4f83df68]
4

由于使用的是get获取对象方式,所以执行第一行的时候就会去数据库执行select语句,但是只select了category表,此时session缓存中只有一个Category对象。执行了第三行,仍旧没有select product。只有到第5行使用到了该Category对象的product列表时,才会去数据库查询product_表,session缓存中也加入了3个Product对象。

 

关系的延迟加载方式对load也一样,只有使用到了Category对象的product列表时,才去数据库查询product_表。

        Category category=(Category) session.load(Category.class,1);
        System.out.println(session.getStatistics().getEntityCount());
        System.out.println(category);
        System.out.println(session.getStatistics().getEntityCount());
        System.out.println(category.getProduct());
        System.out.println(session.getStatistics().getEntityCount());

控制台打印结果:

0
Hibernate: select category0_.id as id2_0_, category0_.name as name2_0_ from category_ category0_ where category0_.id=?
pojo.Category@478190fc
1
Hibernate: select product0_.cid as cid2_1_, product0_.id as id1_, product0_.id as id0_0_, product0_.name as name0_0_, product0_.price as price0_0_ from product_ product0_ where product0_.cid=?
[pojo.Product@1bd4fdd, pojo.Product@7d8995e, pojo.Product@6cf0e0ba]
4

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值