属性的延迟加载
在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