Lazy loading:
Lazy loading mechanism is in order to avoid unnecessary performance overhead and put forward the so-called lazy loading is required when the real data at a time when the real implementation of the data load operation. At Hibernate provides for lazy loading object entities, as well as a collection of lazy loading, while at Hibernate3 also provides the property lazy loading. The following we will separately introduce these types of delays in loading details.
A, the lazy loading object entities:
If you want to use lazy loading object entities must be in the entity mapping configuration file corresponding to the configuration, as follows:
<hibernate-mapping>
<class name="com.neusoft.entity.User" table="user" lazy="true">
... ...
</ class>
</ hibernate-mapping>
By class of lazy property set to true, to open the physical characteristics of the delayed load. 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 by the data query, 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 memory snapshot, we will be surprised to find that At this point the possibility of return are User $ EnhancerByCGLIB $ $ bede8986 type of object, and its property for the null, This is how the matter? Also remember that I have said in front of session.load () method will return the agent entity object class object here is to return the object type User agent object class object. In Hibernate by using CGLIB, to achieve the dynamic structure of a targeting agent class object, and agent class object in the target audience includes all properties and methods, and all property were assigned to null. Through the debugger to display memory snapshot, we can see real time User objects are included in the agent object 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 property to null, if not empty , then call the getName method of the target audience, if it is empty, will be initiated database queries to generate SQL statements like this: select * from user where'1 '; to query data and target structure and its assignment to Medium property CGLIB $ CALBACK_0.target.
In this way, through an agent between the object, Hibernate implementation of the lazy loading entities, and only initiated when a user access to real property entity object moves, the only real database query operation will be initiated. Entities so lazy loading is completed through the middle category of the agent, so only session.load () method will use lazy loading entities, since only session.load () method will return the agent entity class type object.
B, the collection types of lazy loading:
At Hibernate's lazy loading mechanism for collection of types of applications, meaning are the most significant, because it has the potential to substantially improve the performance of this Hibernate a lot of efforts, including the implementation of an independent JDK Collection , we have one-to-many association, the definition used to accommodate the associated object Set collection, not java.util.Set type or its subtype, but net.sf.hibernate.collection.Set type, through the use of custom collections of implementation, Hibernate implementation of the collection of types of lazy loading. Type of collection in order to use lazy loading, we must configure the following types of U.S. entities regarding 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 property set to true to open the collection of types of lazy loading features. We look 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 the (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 According to the cache data indexing eligible to eligible entities search object.
Here, we introduced a new concept - the data index, the following, we will first take what is a data indexing. Hibernate collections at the type of cache, the cache are divided into two parts, first of all, set the cache id list of all entities, then the object cache entities, these entities object id list is the so-called data indexing. When the search data indexing, if the data did not find the corresponding index, then select SQL will be an implementation consistent with the conditions of access to data and tectonic entity object collection and data indexing, then return a collection of entity objects, and entity objects index and data into the cache of Hibernate. On the other hand, if the data to find the corresponding index, the index to retrieve data from the id list, then under the id in the cache corresponding search entity, if found on the back from the cache, if not found, was launched at select SQL query . Here we see another problem, this problem may have an impact on performance, which is a collection type of cache strategy. 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 <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 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 the code, which 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 table query operation, why is this so? This is because when the first load entities, in accordance with the strategy set the type of cache configuration, data collection only to index the cache, but did not set the entity object cache, so once again in the second plus contained entity, Hibernate entities to find the corresponding index data, but according to data indexing, but not in the cache to find the corresponding entities, so Hibernate data according to the index was launched to find two select SQL query operation, where caused by the Properties of waste, how can we avoid such a situation? We need to set the type of entities designated cache strategy, so we have to 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 entity cache, if the basis of this configuration to run again 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 will no longer have the data index 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, property lazy loading:
In Hibernate3, the introduction of a new characteristic - the property lazy loading, the mechanism for access to high-performance queries provide a powerful tool. We are talking about in front of large data objects to read when the User object has a resume field, the field is a java.sql.Clob type, contains the information the user's resume, when we load the object, we may not be every time we do not load this field, regardless of whether we really need it, and such large data object to read in itself will contribute to a significant performance overhead. At Hibernate2, we have ahead of us talked about only through the surface properties of particle size breakdown to decomposition User category, to solve this problem (please refer to the section of the paper), but at Hibernate3, we can delay the increase in property contains a mechanism to give us only when we really need to operate this field only when the go to read the field data, for which we must configure the following types of U.S. entities:
<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 property settings true to open the property lazy loading, in Hibernate3 in property in order to achieve the lazy loading, the use of the category enhancer to the Class of the entity class file intensive treatment, by enhancing the browser's increased, and the callback mechanism will CGLIB logic, add entity class, where we can see that the lazy loading property, or through CGLIB achieved. CGLIB is an Apache open source projects, this class library can manipulate java bytecode category, according to byte-code to dynamically constructed to meet the requirements of the class 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 be generated similar to the following SQL statement:
Select id, age, name from user where name = 'zx';
Hibernate will then retrieve User entity in all non-lazy loading property corresponding field data, when the Executive to (2) Department will be generated similar to the following SQL statement:
Select resume from user where'1 ';
At this time will be launched on the resume field data read operation of the real