This article describes the principle and implementation method of Hibernate delay loading. Share it for your reference, as follows:
To further optimize the performance of Hibernate, you can use:
Latency loading technology, managing data crawling strategies, and performing cache management to improve the performance of Hibernate.
1. Delay loading (load)
Lazy loading is a mechanism provided by Hibernate to improve program execution efficiency, that is, it will be created only when the data of the object is actually used.
The process of lazy loading: Delay loading is achieved through the proxy mechanism. When Hibernate obtains data from a certain object from a database, when obtaining the collection attribute value of an object, or when obtaining another object associated with an object, since the data of the object is not used (except the identifier), Hibernate does not load the real data from the database, but just creates a proxy object for the object to represent the object. All attributes on this object are the default values; this real object is created only when the data of the object is really needed to be used, and its data is actually loaded from the database.
When the load() method on the Session is called to load an entity; when the Session loads an entity, the collection attribute value in the entity will be loaded with delayed loading; when the Session loads an entity, the other entity object that the entity is single-ended, the delayed loading will be used for another entity object associated with the single-ended
Turn off lazy loading: When loading a single entity, you can use the get() method.
For collection attributes in entities, you can add attribute lazy="false" to this set (<set>, <bag>, <list>…) . When a single-ended association of another entity object, you can configure <one-to-one>, <many-to-one> to add attribute lazy="false" in the mapping file Note: one-to-one cannot have constrained=true (the foreign key is displayed in the generated SQL statement), otherwise lazy loading will not work.
2. The main types of lazy loading are used in Hibernate by default:
• Lazy loading is used when the load() method on the Session is called to load an entity.
• When a Session loads an entity, the collection attribute values in this entity are loaded with delay. (one-to-many)
• When a Session loads an entity, another entity object that is single-ended (one-to-one, many-to-one) associated with the entity is lazy loaded.
• The difference between the second and third is: in the second case, the method to cancel delay loading is to set the lazy loading attribute lazy="false" after the set tag of the mapping file of the one party that has the set attribute; in the third case, the many-to-one tag in the mapping file of the multiple party that has the many-to-one, that is, the many-to-one tag is set.
Objects that can be lazy loaded are all rewritten proxy objects. When the associated session is not closed, accessing the properties of these lazy loaded objects (proxy) (except getId and getClass) hibernate will initialize these proxy, or use Hibernate.initialize(proxy) to initialize proxy objects; when the associated session is closed, an exception will occur to access the lazy loaded object.
3. Crawl strategy (fetch)
Configure the "crawl policy" to directly affect the query effect of the get() and load() methods of the session.
Crawl strategy on single-ended association <many-to-one><one-to_one>:
You can add fetch attributes to single-ended associated mapping elements. select: Delay loading; join: Use an intra-connection in the same select statement to obtain the object's data and the data of its associated object. At this time, the delay loading of the associated object is invalid.
Crawl strategy on collection properties :
select: Delay loading; join: Use intra-joining in the same select statement to obtain the other party's association set. At this time, the lazy on the associated set will be invalid. subselect: Send another query statement or subquery to crawl. This strategy also works for HQL queries.
4. Lazy load case analysis
Case 1: A single entity calls the load() method to cancel lazy loading
package com.hbsi.test;import org.hibernate.Session;import org.junit.Test;import com.hbsi.domain.User;import com.hbsi.utils.HibernateUtil;publicclass TestLazy {//Test get() method;get() method will always execute sql statements @Testpublicvoid testGet(){Session session = HibernateUtil.getSession();User user = (User) session.get(User.class,1);// System.out.println(user.getName());HibernateUtil.close();//Note here: Even if the session is closed and the user is in the managed state, the user object can still be used; this is because although it is in the managed state, this object is an object with attribute values and does not delete it, but only isolates the channel for its dealing with the database. System.out.println(user.getName());}//Testload() method; do not execute the sql statement, and only execute @Testpublicvoid testLoad(){Session session = HibernateUtil.getSession();User user = (User) session.load(User.class,1);//The output id here will not execute the sql statement. It will directly obtain the id from the id you passed in above. It is not searched from the database, so the sql statement System.out.println(user.getId());//The output name is different. At this time, the proxy object is actually instantiated. This is the proxy object with the name attribute. At this time, even if you close the session, you can still get the name through this object. If you comment this sentence, that is, the proxy object does not instantiate the proxy object, and then execute the output name attribute after closing the session, an error will be reported: could not initialize proxy// System.out.println(user.getName());HibernateUtil.close();System.out.println(user.getName());}}Situation 2: Cancel lazy loading on set
Test If the lazy load in the collection attribute is set to false in the mapping file, it will be put together with the data in the orders table, that is, two select statements
@Testpublicvoid find(){Session session = HibernateUtil.getSession();Customer cus = (Customer) session.get(Customer.class,3);System.out.println(cus.getCname());//Use the following method to output the SQL statements for two days, and they are separated; if lazy loading is used, two SQL statements will be output first, and the output result is //The method cannot be directly chained here to output cus.getOrd().getOname(); because cus.getOrd() returns a set set Set<Orders> orders = cus.getOrd();System.err.println(orders.size());HibernateUtil.close();}Method 3: <one-to-one>,<many-to-one> Cancel lazy loading
@Testpublicvoid find(){//By default, lazy loading, that is, output one with an sql statement; if delay loading is set to false and output two sql statements, unwanted customer information will be found. Session session = HibernateUtil.getSession();Orders ord = (Orders) session.get(Orders.class,3);System.out.println(ord.getOname());HibernateUtil.close();}I hope that the description in this article will be helpful to everyone's Java programming based on the Hibernate framework.