Hibernate lazy loading mechanism

Lazy loading:
Lazy loading mechanism is in order to avoid unnecessary performance overhead and put forward the so-called lazy loading is that when data in the real needs when we come to the real implementation of the data load operation. Provided in the Hibernate entity objects to the delay of loading and lazy loading of collections, while in Hibernate3 also provides lazy loading attributes. Here we have introduced these types of delays in loading details.
A, the delay in the target entity to load:
If you want to object to the use of lazy loading entities, entities must be mapped in the configuration file corresponding to the configuration, as follows:
<hibernate-mapping>
<class name="com.neusoft.entity.User" table="user" lazy="true">
... ...
</ class>
</ hibernate-mapping>
Class by the lazy attribute set to true, to open the physical characteristics of the delay in loading. If we run the following code:
User user = (User) session.load (User.class, "1"); (1)
System.out.println (user.getName ());( 2)
When I run into (1) when, Hibernate has not initiated the query data, if we are at this time through a number of debugging tools (such as the Debug tool JBuilder2005), observed at this time the target user's memory snapshot, we will be surprised to find that may be returned at this time User $ EnhancerByCGLIB $ $ bede8986 types of objects and their attributes to null, how this is going on? I still remember the front of said session.load () method will return a proxy object entity class object, the object here to return to the type of agent is the User object class object. Through the use of Hibernate in the CGLIB, to achieve the target to construct a dynamic proxy class object, and objects in the proxy class contains all the attributes of the target audience and methods, and all the attributes are assigned to null. Through the debugger to display a snapshot of memory, we can see real time User object is included in the proxy object of CGLIB $ CALBACK_0.target property, when the code is running into (2) when, at this time call user.getName () method, when given through CGLIB callback mechanism, in fact, called CGLIB $ CALBACK_0.getName () method, when calling the method, Hibernate will first check whether the CGLIB $ CALBACK_0.target properties for null, if not empty , then call the getName method of targeting, if it is empty, database query will be initiated to generate a SQL statement like this: select * from user where'1 '; to query data and target structure and its assignment to CGLIB $ CALBACK_0.target properties.
In this way, through an intermediate proxy object, Hibernate delay the achievement of the entity to load, and only initiated when a user access to the real property entity object moves only when a real database query operation was launched. Therefore, the delayed entity loading is completed through the intermediate proxy class, so only session.load () method will use lazy loading entities, since only session.load () method will only return entities of type proxy class object.
B, the collection types of lazy loading:
In Hibernate's lazy loading mechanism for the collection of types of applications, the meaning is the most significant, because it has the potential to significantly improve the performance of this Hibernate a lot of efforts, including the realization of an independent JDK Collection , we have one-to-many association, the definition of the object used to accommodate the associated Set collection, not java.util.Set type or subtype, but net.sf.hibernate.collection.Set type, through the use of custom the realization of collections, Hibernate types of the realization of a collection of lazy loading. In order to set the type to use lazy loading, we have the following configuration of our entity class on the related 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>
<set> Elements by lazy attribute set to true to open the collection of types of load characteristics of the delay. 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 procedure to (1) when, at this time will not be launched on the associated data query to load the associated data, only to run into (2) when the real data read operation will start, then Hibernate will eligible in accordance with the cache index of data to find eligible entity object.
Here we introduce a new concept - the data index, the following first of all, we will take what is the data index. Set in the Hibernate type of cache, the cache is divided into two parts, first of all, set the cache id of the list of all entities, and then cached entity object, the object id list of entities is the so-called index of the data. When the index to find data, if data did not find the corresponding index, then select SQL will be an implementation consistent with the conditions of access to data and physical object structure and data index set, and then return a collection of entity objects and entity objects will be index and data into the cache of Hibernate. On the other hand, if the data to find the corresponding index data from the index list out of id, and then under the id in the cache to find the corresponding entities, if found on the return from the cache, if not found in the select SQL query initiated . Here we see another issue that may have an impact on performance, this type of cache is a collection strategy. If we set the type of configuration is as follows:
<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 <cache usage="read-only"/> configuration, if we adopt this strategy to set the type of configuration, Hibernate will only index the data cache, rather than a collection of entities on the object cache . Above configuration, 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 implementation of the second inquiry, carried out two pairs of address form query operation, the reason for this? This is because the load when the first entity, in accordance with the strategy set the type of cache configuration, data collection only index the cache and are not a collection of entities of the object cache, so once again in the second increase contained entity, Hibernate entities to find the corresponding index data, but the data index, but not in the cache to find the corresponding entities, the Hibernate data based on the index was launched to find two of the select SQL query operation, where the cause of a waste of performance and how to avoid such a situation? We need to set the type of entity in the cache strategy is also specified, and so we must set the following types of configurations:
<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 will now set the type of entities in the cache, if the basis of this configuration to run the above code again, 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 data of the SQL query statement, because at this time can be obtained directly from the cache storage of a collection of entity types in the object.
C, attributes the delay to load:
In Hibernate3, the introduction of a new characteristic - attributes the delay to load, this mechanism for obtaining high-performance queries provide a powerful tool. We are talking about in front of large data objects to read when the User object in the resume, there is a field, the field is a java.sql.Clob type, contains information on the user's curriculum vitae, when we load the object, we may not be 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 a lot of performance overhead. In Hibernate2, we have before us only through the surface properties of said sub-grain size to decomposition User category, to address this issue (please refer to the section of the paper), but in Hibernate3, we can attribute the delay increases contains a mechanism to give us only when we really need to operate the field before trying to read data in this field, 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> Elements of lazy attribute set to open the properties of true delayed loading, in order to achieve in Hibernate3 lazy attribute, use the type of enhancer for the Class of the entity class to strengthen the document processing, by enhancing the browser's increased, and the callback mechanism will CGLIB logic, adding entity class, where we can see that the lazy loading attribute, or achieved through CGLIB. CGLIB is an Apache open source projects, this type of class library can manipulate java byte code to byte-code based on the dynamic structure to meet the requirements of the type of object. According to the above configuration, we 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 will generate the SQL statement similar to the following:
Select id, age, name from user where name = 'zx';
Hibernate will then retrieve User entity attribute all non-lazy loading the corresponding field data, when the implementation of the (2) The Department will generate the SQL statement similar to the following:
Select resume from user where'1 ';
Will be launched at this time to resume the real field data read operation.

分类:Java 时间:2009-09-18 人气:1434
分享到:
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.345 (s). 12 q(s)