Deferred loading:first of all, Hibernate3 delay loading only a number of load,get,find some of the internal value methods useful, for HQL, such as the invalid write SQL. The delay loading mechanism is to avoid some unnecessary performance overhead, the so-called delay loading is when the real need for data, the real implementation of data loading operations. In theHibernateprovides deferred loading of entity objects and deferred loading of the collection, in addition to theHibernate3a deferred load on a property is also provided in. Let's go through the details of these kinds of deferred loading separately. A,deferred loading of entity objects:If you want to use deferred loading on entity objects, you must configure them in the mapping configuration file for the entity, as follows:<class name= "Com.neusoft.entity.User" table= "User" lazy= "true" > .....</class>by puttingclassof theLazyproperty is set totrueto open the deferred loading attribute 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 you run to(1)Place,Hibernateno queries have been initiated on the data, if we pass some debugging tools at this time(likeJBuilder2005of theDebugTools), observe this timeUserThe memory snapshot of the object, we will be surprised to find that at this time the return may beuser$enhancerbycglib$ $bede 8986The object of the type, and its properties areNULL,What's going on here. Remember when I told you beforesession.load ()method returns the proxy class object for the entity object, and the object type returned here isUserthe proxy class object for the object. In theHibernateby using theCglib,to implement a proxy class object that dynamically constructs a target object, and contains all the properties and methods of the target object in the proxy class object, and all attributes are assigned toNULL. With the memory snapshot shown by the debugger, we can see that at this point the realUserobject that is contained in the proxy object.Cglib$calback_0.targetproperty, when the code runs to (2) is called at this time.User.getname ()method at this time byCglibGiven the callback mechanism that actually calls theCglib$calback_0.getname ()method, when the method is called,Hibernatewill first checkCglib$calback_0.targetwhether the property isNULL, if not NULL, the target object'sGetNamemethod, if it is empty, a database query is initiated to generate a similarSQLstatement:SELECT * from user where id= ' 1 ';to query the data and construct the target object, and assign it to theCglib$calback_0.targetproperty. so, through an intermediate proxy object,Hibernateimplement the delay loading of the entity, only when the user really initiates the action of obtaining the attributes of the entity object, the database query operation is really initiated. So the delay loading of the entity is done through the intermediate proxy class, so onlysession.load ()method to use entity delay loading because onlysession.load ()method returns the proxy class object for the entity class. B,deferred loading of collection types:in theHibernatedelay loading mechanism, for the application of the set type, the significance is the most important, because it is possible to greatly improve performance, soHibernateA great deal of effort has been made, including theJDK CollectionIn a One-to-many association, defined to hold the associated objectSetcollection, notJava.util.Settype or its subtypes, but ratherNet.sf.hibernate.collection.Settype, by using the implementation of the custom collection class ,Hibernatedeferred loading of the collection type was implemented. In order to use deferred loading for the collection type, we must configure the associated part of our entity class as follows:<class name= "Com.neusoft.entity.User" table= "User" > ....<set name= "addresses" table= "Address" lazy= "true" inverse= "true" ><key column= "user_id"/><one-to-many class= "Com.neusoft.entity.Arrderss"/></set></class>by putting<set>Elements ofLazyproperty is set totrueto open the deferred load attribute of the collection type. Let's look at 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 executes to(1), this does not initiate a query to the associated data to load the associated data, only the(2), the real data-reading operation will begin whenHibernatefinds entity objects that match the criteria based on the data index that matches the criteria in the cache. here we introduce a whole new concept--data index, and we'll take a look at what the data index is first. In theHibernateis cached in two parts when the collection type is cached, first caching all entities in the collection .IDlist, and then caching the entity objects, whichIDlist, which is called the data index. When looking for a data index, if the corresponding data index is not found, aSelect SQL, get the data that meets the criteria, construct the collection of entity objects and data indexes, and then return the collection of entity objects and include the entity objects and data IndexesHibernateCache. If, on the other hand, the corresponding data index is found, it is removed from the data indexIDlist, and then according to theIDfind the corresponding entity in the cache, and if found, return from the cache, if not found, in the initiatingSelect SQLquery. Here we see another problem that may have an impact on performance, which is the caching strategy for the collection type. If we configure the collection type as follows:<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 class= "Com.neusoft.entity.Arrderss"/></set></class>here we have applied<cache usage= "read-only"/>configuration, if this policy is used to configure the collection type,HibernateThe data index is cached only, not the entity objects in the collection. As configured above 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 ());}running this code will get output similar to the following:Select * from user where id= ' 1 ';Select * From address where user_id= ' 1 ';TianjinDalianSecond Query ...Select * From address where id= ' 1 ';Select * From address where id= ' 2 ';TianjinDalianwe see that when the query executes the second time, two pairs of AddressTable Query operation, why is this. This is because when an entity is loaded for the first time, the collection data index is cached based on the configuration of the collection type caching policy, and the entity objects in the collection are not cached, so the second time the entity is loaded again,HibernateThe data index for the corresponding entity was found, but the corresponding entity could not be found in the cache based on the data index, soHibernateTwo articles were launched based on the data index foundSelect SQLquery operation, which has caused a waste of performance, how to avoid this situation. We must also specify a caching policy for the entities in the collection type, so we have to configure the collection type as follows:<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 class= "Com.neusoft.entity.Arrderss"/></set></class>at this pointHibernateThe entities in the collection type are also cached, and if you run the above code again based on this configuration, you will get output similar to the following:Select * from user where id= ' 1 ';Select * From address where user_id= ' 1 ';TianjinDalianSecond Query ...TianjinDalianthere will be no more queries based on the data index.SQLstatement, because the entity objects stored in the collection type can be obtained directly from the cache at this time. C,Property Deferred loading:in theHibernate3, a new feature-deferred loading of attributes-is introduced, which provides a powerful tool for obtaining high-performance queries. Before we talk about the large data object reading, theUserthe object has aResumefield, which is aJava.sql.Clobtype, which contains the user's resume information, and when we load the object, we have to load the field every time, regardless of whether we really need it, and the reading of such a large data object can have a significant performance overhead. In theHibernate2, we can only decompose the particle size of the surface performance we talked about earlier.Userclass to solve the problem (refer to the section), butHibernate3, we can get the ability to read the field data only when we really need to manipulate the field, so we have to configure our entity classes as follows:<class name= "Com.neusoft.entity.User" table= "User" > .....<property name= "Resume" type= " Java.sql.Clob" column= "Resume" lazy= "true"/></class>through the<property>Elements ofLazyProperty Settingstrueto turn on deferred loading of the property,Hibernate3class intensifier is used to implement the deferred loading of the attribute for the entity classClassThe enhanced processing of the file, through the enhancement of the amplifier, willCglibcallback mechanism logic, add the entity class, where we can see the delay loading of the property, or theCglibto achieve. CglibisApachean open source project, this class library can manipulateJavaThe byte code of the class that dynamically constructs the class object that conforms to the requirement based on the byte code. Based on the configuration above, we run the following code:String sql= "from 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 executing to(1), you will generate a similarSQLstatement:Select id,age,name from user where name= ' ZX ';thenHibernatewill retrieveUserthe field data for all non-deferred load properties in the entity, when executed to the(2), you will generate a similarSQLstatement:Select resume from user where id= ' 1 ';This will initiate theResumethe actual read operation of the field data.
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.