Home >Backend Development >PHP Tutorial >Three types of lazy loading in Hibernate_PHP tutorial
Persistence: The object establishes a corresponding relationship with the database record and maintains synchronization. The object is bound to the persistence context, and any future state changes and data changes will be under the management of the work unit. This is the persistence state. Session.load is the default lazy loading method provided in hibernate3.2. I think what is loaded is a proxy, which can also be said to be persistent state.
The lazy loading mechanism is proposed to avoid unnecessary performance overhead. The so-called lazy loading means that the data loading operation is actually performed when the data is actually needed. When using delayed loading, the object used is a proxy object, which contains all member variables and methods of the proxy object. However, in this object, the value of the member variable is NULL, and Hibernate provides a pair of entities. Lazy loading of objects and lazy loading of collections. In addition, Hibernate3 also provides lazy loading of properties. Below we will introduce the details of these types of lazy loading respectively.
A. Lazy loading of entity objects:
If you want to use lazy loading for entity objects, you must configure it accordingly in the entity's mapping configuration file, as shown below:
… …
By setting the lazy attribute of the class to true, you can turn on the lazy loading feature of the entity. 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), Hibernate does not initiate a query for data. If we use some debugging tools (such as the Debug tool of JBuilder2005) or use debug breakpoint monitoring, the memory snapshot of the user object at this time, we You will be surprised to find that what is returned at this time may be an object of type User$EnhancerByCGLIB$$bede8986, and its attribute is null. The session.load() method will return the proxy class object of the entity object. The object type returned here is the proxy class object of the User object. In Hibernate, CGLIB is used to dynamically construct a proxy class object of the target object, and the proxy class object contains all properties and methods of the target object, and all properties are assigned null. Through the memory snapshot displayed by the debugger, we can see that the real User object at this time is contained in the CGLIB$CALBACK_0.target attribute of the proxy object,
When the code runs to (2), the user.getName() method is called. At this time, through the callback mechanism given by CGLIB, the CGLIB$CALBACK_0.getName() method is actually called. When this method is called, Hibernate will first Check whether the CGLIB$CALBACK_0.target attribute is null. If it is not null, call the getName method of the target object. If it is null, a database query will be initiated to generate a SQL statement similar to this: select * from user where id='1 '; to query the data, construct the target object, and assign it to the CGLIB$CALBACK_0.target attribute. In this way, through an intermediate proxy object, Hibernate implements lazy loading of entities. Only when the user actually initiates an action to obtain the attributes of the entity object, the database query operation will actually be initiated. Therefore, the lazy loading of entities is completed through the intermediate proxy class, so only the session.load() method will use the lazy loading of entities, because only the session.load() method will return the proxy class object of the entity class.
B. Lazy loading of collection types:
Among Hibernate's lazy loading mechanisms, the application of collection types is the most significant, because it is possible to greatly improve performance. To this end, Hibernate has made a lot of efforts, including the independent implementation of JDK Collection. In one-to-many relationships, the Set collection we define to accommodate associated objects is not of the java.util.Set type or its subtypes, but of the net.sf.hibernate.collection.Set type, by using a custom collection class Implementation, Hibernate implements lazy loading of collection types. In order to use lazy loading for collection types, we must configure the association part of our entity class as follows:
…
in
Turn on the lazy loading feature of the collection type by setting the lazy attribute of the
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 executes to (1), it will not initiate a query for related data to load the related data. Only when it runs to (2), the real data reading operation will begin. At this time, Hibernate will start based on Use the qualified data index in the cache to find qualified entity objects. Here we introduce a new concept - data index. Next we will first take a look at what a data index is. When caching a collection type in Hibernate, it is cached in two parts. First, the id list of all entities in the collection is cached, and then the entity objects are cached. The id list of these entity objects is the so-called data index. When searching for a data index, if the corresponding data index is not found, a select SQL will be executed to obtain qualified data, construct a collection of entity objects and a data index, then return a collection of entity objects, and add the entity object and data indexes into Hibernate's cache. On the other hand, if the corresponding data index is found, the id list is taken from the data index, and then the corresponding entity is searched in the cache according to the id. If found, it is returned from the cache. If not found, a select SQL query is initiated. Here we see another problem that may have an impact on performance, which is the caching strategy of the collection type. If we configure the collection type as follows:
…..
Here we apply the
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());
}
When you run this code, you will get output similar to the following:
Select * from user where id=’1’;
Select * from address where user_id=’1’;
Tianjin
Dalian
Second query……
Select * from address where id=’1’;
Select * from address where id=’2’;
Tianjin
Dalian
We see that when the query is executed for the second time, two query operations on the address table are executed. Why is this? This is because when the entity is loaded for the first time, according to the configuration of the collection type cache strategy, only the collection data index is cached, but the entity objects in the collection are not cached. Therefore, when the entity is loaded again for the second time, Hibernate found the data index of the corresponding entity, but according to the data index, it could not find the corresponding entity in the cache. Therefore, Hibernate initiated two select SQL query operations based on the found data index. This caused a waste of performance. How? How can this be avoided? We must also specify a cache strategy for the entities in the collection type, so we need to configure the collection type as follows:
…..
At this time, Hibernate will also cache the entities in the collection type. If you run the above code again according to this configuration, you will get output similar to the following:
Select * from user where id=’1’;
Select * from address where user_id=’1’;
Tianjin
Dalian
Second query……
Tianjin
Dalian
At this time, there will be no more SQL statements to query based on the data index, because the entity objects stored in the collection type can be obtained directly from the cache.
C. Attribute lazy loading:
In Hibernate3, a new feature is introduced - lazy loading of properties. This mechanism provides a powerful tool for obtaining high-performance queries. When we talked about reading big data objects earlier, there is a resume field in the User object. This field is a java.sql.Clob type and contains the user's resume information. When we load the object, we have to load it every time. This field must be loaded regardless of whether we really need it, and the reading of this large data object itself will bring a lot of performance overhead. In Hibernate2, we can only solve this problem by decomposing the User class through the granular segmentation of performance as we mentioned earlier (please refer to the discussion in that section), but in Hibernate3, we can use the attribute lazy loading mechanism , so that we can obtain the ability to read the data of this field only when we really need to operate this field. For this reason, we must configure our entity class as follows:
……
Enable lazy loading of properties by setting true to the lazy attribute of the
String sql=”from User user where user.name=’zx’ ”;
Query query=session.createQuery(sql); (1)
List list=query.list();
for(int i=0;i
System.out.println(user.getName());
System.out.println(user.getResume()); (2)
}
When execution reaches (1), a SQL statement similar to the following will be generated:
Select id,age,name from user where name=’zx’;www.2cto.com
At this time, Hibernate will retrieve the field data corresponding to all non-lazy loading attributes in the User entity. When executing (2), a SQL statement similar to the following will be generated:
Select resume from user where id=’1’;
At this time, the actual reading operation of the resume field data will be initiated.
Author: oh_Mourinho