Hibernate lazy-loading mechanism for Xiang Jie

Lazy:

Lazy loading mechanism is in order to avoid unnecessary performance overhead and put forward the so-called lazy loading is that when the data really need when we come to the genuine implementation of data loading operations. Provided in the Hibernate entity objects as well as a collection of delay in loading delays in loading, while in Hibernate3 also provides the right attributes lazy. Here we introduce these types of delays were loaded details.

A, physical object delay load:

If you want to use lazy loading of the entity object must be in the physical mapping of the configuration file for the appropriate configuration, as follows:

<hibernate-mapping>

<class name="com.neusoft.entity.User" table="user" lazy="true">

... ...

</ class>

</ hibernate-mapping>

By class of lazy property is set to true, to open the physical characteristics of the delayed loading. If we run the following code:

User user = (User) session.load (User.class, "1"); (1)

System.out.println (user.getName ());( 2)

When running to (1), Office hours, Hibernate does not initiate a data query, if we are at this time through a number of debugging tools (such as JBuilder2005 the Debug tool) to observe the user at this time the object of memory snapshots, we will be surprised to find that At this point may be returned User $ EnhancerByCGLIB $ $ bede8986 types of objects and their attributes as null, which is how it? Remember earlier I had talked session.load () method will return a proxy class object physical object, where the returned object type is the User object's proxy class object. In the Hibernate by using CGLIB, to construct a target object dynamic proxy class object, and in the proxy class object contains all of the target object properties and methods, and all attributes are assigned to null. Through the debugger shows the memory snapshot, we can see the real time User objects, is included in the proxy object CGLIB $ CALBACK_0.target property, when the code runs to (2), Office hours, this time called user.getName () method, when given by CGLIB callback mechanism, in fact call the CGLIB $ CALBACK_0.getName () method, when you call the method, Hibernate will first check the CGLIB $ CALBACK_0.target property is null, if not empty , then call the target object's getName method, if empty, it will initiate database queries, the generated SQL statement like this: select * from user where'1 '; to query data, and construct the target object, and assign it to a CGLIB $ CALBACK_0.target properties.

In this way, through an intermediate proxy object, Hibernate implements lazy loading entities, and only when a user actually initiated the action to obtain physical object properties only when the real action will be initiated database queries. Therefore, the delayed entity loading is done through the intermediate proxy class, so only session.load () method will only delay the use of physical load, because only session.load () method will return a proxy class object entity class.

B, a collection of types of lazy loading:

In Hibernate's lazy loading mechanism for the collection types of applications, meaning the most significant, because it has the potential to significantly improve the performance, for Hibernate carried out a lot of efforts, including an independent realization of JDK Collection , we have one to many association, the definition is used to hold a collection of related object of the Set is not java.util.Set type or its sub-types, but net.sf.hibernate.collection.Set type, by using a custom collection class implementation, Hibernate implements lazy loading collection types. In order to set the type to use lazy loading, we have the following configuration of our entity class on the associated parts:

<hibernate-mapping>

<class name="com.neusoft.entity.User" table="user">

... ..

<set name="addresses" table="address" lazy="true" inverse="true">

<key column="user_id"/>

<one-to-many"com.neusoft.entity.Arrderss"/>

</ set>

</ class>

</ hibernate-mapping>

By <set> element lazy attribute set to true to open the collection type of lazy loading features. We see the following code:

User user = (User) session.load (User.class, "1");

Collection addset = user.getAddresses (); (1)

Iterator it = addset.iterator (); (2)

while (it.hasNext ()) (

Address address = (Address) it.next ();

System.out.println (address.getAddress ());

)

When the program execution to (1) Offices, the time will not initiate a query to load the associated data associated with the data, only to run to (2) Offices, the real data read operation will not start, then Hibernate will be According to the data cache eligible index to find qualified entity objects.

Here we introduce a new concept - data index, let's first take look at what is data indexing. Hibernate collection type in the right cache when the cache is divided into two parts, first of all entities in the cache set id list, and then cached entity object, the object id list of these entities is the so-called data index. When the search for data indexing, if not find the corresponding data index, then the implementation will be a select SQL, access to meet the requirements of the data, and construct a collection of physical objects and the data index, and then return a collection of physical objects and entity objects and data into an index into the cache of Hibernate. On the other hand, if the data to find the corresponding index data indexing remove id from list, and then under the id in the cache to find the corresponding entities, if found from the cache to return if not found, in initiating select SQL query. Here we see another issue that may have an impact on performance, which is a collection of types of caching policy. If we set the following configuration types:

<hibernate-mapping>

<class name="com.neusoft.entity.User" table="user">

... ..

<set name="addresses" table="address" lazy="true" inverse="true">

<cache usage="read-only"/>

<key column="user_id"/>

<one-to-many"com.neusoft.entity.Arrderss"/>

</ set>

</ class>

</ hibernate-mapping>

Here we applied the <cache usage="read-only"/> configuration, if we adopt this strategy to configure the collection type, Hibernate will only index the data cache, rather than a collection of entity objects will be cached. As configured we run the following code:

User user = (User) session.load (User.class, "1");

Collection addset = user.getAddresses ();

Iterator it = addset.iterator ();

while (it.hasNext ()) (

Address address = (Address) it.next ();

System.out.println (address.getAddress ());

)

System.out.println ( "Second query ... ...");

User user2 = (User) session.load (User.class, "1");

Collection it2 = user2.getAddresses ();

while (it2.hasNext ()) (

Address address2 = (Address) it2.next ();

System.out.println (address2.getAddress ());

)

Run this code, will be similar to the following output:

Select * from user where'1 ';

Select * from address where user_id = '1 ';

Tianjin

Dalian

Second query ... ...

Select * from address where'1 ';

Select * from address where'2 ';

Tianjin

Dalian

We can see that the second query is executed, the implementation of the two pairs of address table query operation, why is this so? This is because when you first load an entity, based on the configuration of the collection type of caching strategy, data collection only index the cache, but did not set the entity object cache, so in the second re-load the entity , Hibernate entity to find the corresponding data index, but according to data indexing, but can not be found in the cache corresponding to the entities, so Hibernate according to the data found in the index was launched two select SQL query operation, where the performance resulted in waste, How can we avoid this situation? We must set the type of the entities designated caching strategy, so we have to configure the following types of collections:

<hibernate-mapping>

<class name="com.neusoft.entity.User" table="user">

... ..

<set name="addresses" table="address" lazy="true" inverse="true">

<cache usage="read-write"/>

<key column="user_id"/>

<one-to-many"com.neusoft.entity.Arrderss"/>

</ set>

</ class>

</ hibernate-mapping>

Hibernate collection type at this time would have also carried out in the entity cache, if the basis of this configuration re-run the above code, will be similar to the following output:

Select * from user where'1 ';

Select * from address where user_id = '1 ';

Tianjin

Dalian

Second query ... ...

Tianjin

Dalian

At this time there will not be indexed according to the data of the SQL query statement, because at this time can be obtained directly from the cache stored in a collection of entity object types.

C, attribute lazy:

In Hibernate3, the introduction of a new feature - the property lazy loading, this mechanism also provides for access to high-performance query a powerful tool. When we say in front of large data objects to read when the User object in the field, there is a resume of the field is a java.sql.Clob type that contains the user's curriculum vitae information, when we load the object, we must not do not have to load each time this field, regardless of whether we really need it, and this large data object to read in itself will bring significant performance overhead. In the Hibernate2, we are ahead of us talked about only through the performance of particle size breakdown of the surface to decompose User class, to solve this problem (please refer to the section of the exposition), but in Hibernate3, we can attribute to defer the increase contains a mechanism to give us only when we really need to operate in this field before going to the ability to read the field data, for which we have the following configuration of our entity class:

<hibernate-mapping>

<class name="com.neusoft.entity.User" table="user">

... ...

<property name="resume" type="java.sql.Clob" column="resume" lazy="true"/>

</ class>

</ hibernate-mapping>

<property> Element through the lazy attribute set to open the properties of true delayed loading, in order to achieve the properties in the Hibernate3 delay loading a class using the booster to the Class of the entity class file enhanced processing, by enhancing device enhancements, will CGLIB callback mechanism for the logic, add entity class, where we can see that the property lazy loading, or through CGLIB to achieve. CGLIB is an open source Apache project, the library can manipulate java byte code classes, according to byte code to dynamically constructed to meet the requirements of the class object. Based on the above configuration we have run the following code:

String sql = "from User user where user.name = 'zx'";

Query query = session.createQuery (sql); (1)

List list = query.list ();

for (int i = 0; i <list.size (); i + +) (

User user = (User) list.get (i);

System.out.println (user.getName ());

System.out.println (user.getResume ()); (2)

)

When the Executive to (1) Department, it will generate SQL similar to the following statement:

Select id, age, name from user where name = 'zx';

Hibernate will then retrieve the User entity, all non-lazy properties of the corresponding field data, when the Executive to (2) Department, it will generate SQL similar to the following statement:

Select resume from user where'1 ';

This time to launch a real field data on the resume read operation.

分类:Java 时间:2009-06-05 人气:280
分享到:
blog comments powered by Disqus

相关文章

iOS 开发

Android 开发

Python 开发

JAVA 开发

开发语言

PHP 开发

Ruby 开发

搜索

前端开发

数据库

开发工具

开放平台

Javascript 开发

.NET 开发

云计算

服务器

Copyright (C) codeweblog.com, All Rights Reserved.

CodeWeblog.com 版权所有 黔ICP备15002463号-1

processed in 0.450 (s). 14 q(s)