Overview
- No wasted memory: When Hibernate loads the customer object from the database, if all the associated order objects are loaded at the same time, and the program actually only needs to access the customer object, the associated order objects waste a lot of memory.
- Higher query efficiency: Send As few SQL statements as possible
class-Level retrieval policies
- Class-level optional retrieval policies include immediate retrieval and deferred retrieval, and default to deferred retrieval
- Retrieve now: Load the object specified by the retrieval method immediately
- Deferred retrieval: Lazy loading retrieves the object specified by the method. When you use a specific property, the load
- Class-level retrieval policies can be set by the <class> element's Lazy property
- If the program loads an object that is intended to access its properties, it can take immediate retrieval.
- If the program loads a persisted object for the purpose of obtaining its reference only, a deferred retrieval can be used. Note that lazy loading exceptions appear!
- Whether the <class> element's Lazy property is true or false, the get () method of the Session and the list () method of the Query always use the immediate retrieval policy at the class level
- If the lazy property of the <class> element is true or takes the default value, the Session's load () method does not execute the SELECT statement of the Query data table and returns only the instance of the proxy class object, which has the following characteristics:
- Dynamically generated by Hibernate using the CGLIB tool at run time
- Hibernate Only initializes its OID property when creating an instance of the proxy class
- Hibernate initializes the proxy class instance when the application accesses the non-OID attribute of the proxy class instance for the first time
One-to-many and many-to-many retrieval strategies
In the mapping file, the <set> element is used to configure a one-to-many association and many-to-many association relationships. <set> elements have lazy and fetch attributes
- lazy: The time when the Orders collection is initialized is primarily determined. Whether it is initialized when the Customer object is loaded, or when the program accesses the Orders collection
- Fetch: When a value of "select" or "Subselect" is taken, the form of the query statement that initializes the orders is determined; If the value is "join", the time when the Orders collection is initialized is determined
- If fetch is set to "join", the lazy property is ignored
- The Batch-size attribute of the <set> element: used to set the number of bulk searches for a deferred retrieval policy or an immediate retrieval policy. Bulk retrieval can reduce the number of SELECT statements and improve the performance of deferred or immediate retrieval operations.
<set> lazy and fetch attributes for elements
Delayed retrieval and enhanced deferred retrieval
- Hibernate initializes the collection proxy class instance in the following cases when the deferred retrieval (lazy property value is true) collection property
- The first time the application accesses the collection properties: Iterator (), size (), IsEmpty (), contains (), and other methods
- Explicit initialization via Hibernate.initialize () static method
- Enhanced deferred retrieval (the Lazy property is extra): similar to lazy= "true". The main difference is that the enhanced deferred retrieval strategy can further delay the initialization time of the Orders collection agent instance of the Customer object :
- When a program accesses the iterator () method of the Orders property for the first time, it causes the initialization of the Orders collection proxy class instance
- When a program accesses the size (), contains (), and IsEmpty () methods of the Order property for the first time, Hibernate does not initialize an instance of the Orders collection class, querying only the necessary information through a specific SELECT statement and does not retrieve all ORD Er Object
The Batch-size property <set> element of the <set> element has a Batch-size property that is used to set the number of bulk searches for a deferred retrieval policy or an immediate retrieval policy. Bulk retrieval can reduce the number of SELECT statements and improve the performance of deferred or immediate retrieval operations.
Full batch initialization of the Orders collection with the SELECT statement of the tape query (Fetch attribute "Subselect")
- The fetch attribute of the <set> element: Determines the form of the query statement that initializes the orders when the value is "select" or "Subselect ", and if the value is "join", determines when the orders collection is initialized. Recognition value is Select
- When the Fetch property is "Subselect"
- Assuming that there are N orders collection proxy class instances not initialized in the Session cache, Hibernate is able to batch initialize N orders collection proxy class instances by using the SELECT statement of the tape query
- batch-size property will be ignored
- The SELECT statement in the subquery is a SELECT statement that queries the CUSTOMERS table OID
Urgent left OUTER JOIN search (Fetch attribute value set to "join")
- Fetch attribute of the <set> element: Determines the form of the query statement that initializes the orders when the value is "select" or "Subselect"; If the value is "join", it determines when the Orders collection is initialized . The default value is select
- When the fetch attribute is "join":
- When the Customer object is retrieved, all associated Order objects are retrieved with an urgent left outer join (the object associated with retrieving the specified object is loaded through the left outer join) policy
- The Lazy property is ignored
- The list () method of Query ignores the urgent left-to-outer connection retrieval policy configured in the mapping file and still uses the deferred-loading strategy
Multiple-to-one and single-on-a-link retrieval strategies
- Like <set>, the <many-to-one> element also has a lazy property and a fetch attribute.
- If the fetch attribute is set to join, then the Lazy property is ignored
- The advantage of an urgent left outer join retrieval strategy is that fewer SELECT statements are used than the immediate retrieval policy.
- Agentless latency retrieval requires the enhancement of the byte code of the persisted class to achieve
- The list method of Query ignores the urgent left outer connection retrieval policy of the mapping file configuration, and uses the deferred retrieval strategy
- If you use lazy-load or immediate-load retrieval policies at the association level, you can set the size of the bulk retrieval to help improve the running performance of deferred or immediate retrieval.
- Hibernate allows you to overwrite the retrieval policy set in the mapping file in your application.
Search Policy Summary
Class-level and association-level optional retrieval policies and default retrieval policies
The operating mechanism of 3 kinds of retrieval strategies
Several properties in the mapping file that are used to set the retrieval policy
Three search strategies for comparing Hibernate
Code Explanation: Customer.java
Package Com.atguigu.hibernate.strategy;import Java.util.hashset;import Java.util.set;public class Customer {private Integer customerid;private String customername;private set<order> orders = new hashset<> ();p ublic Integer Getcustomerid () {return customerId;} public void Setcustomerid (Integer customerId) {this.customerid = customerId;} Public String Getcustomername () {return customerName;} public void Setcustomername (String customerName) {this.customername = CustomerName;} Public set<order> getorders () {return orders;} public void Setorders (set<order> orders) {this.orders = orders;}}
Order.java
Package Com.atguigu.hibernate.strategy;public class Order {private Integer orderid;private String ordername;private Customer customer;public Integer Getorderid () {return orderId;} public void Setorderid (Integer orderId) {this.orderid = orderId;} Public String Getordername () {return ordername;} public void Setordername (String ordername) {this.ordername = Ordername;} Public Customer GetCustomer () {return customer;} public void Setcustomer (customer customer) {This.customer = customer;} @Overridepublic int hashcode () {final int prime = 31;int result = 1;result = Prime * result + (orderId = = null)? 0:ord Erid.hashcode ()); return result;} @Overridepublic boolean equals (Object obj) {if (this = = obj) return true;if (obj = = null) return False;if (GetClass ()! = obj . GetClass ()) return false;order other = (Order) obj;if (orderId = = null) {if (Other.orderid! = null) return false;} else if (!orderid.equals (Other.orderid)) return False;return true;}}
Customer.hbm.xml
<?xml version= "1.0"? ><! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en" "http://hibernate.sourceforge.net/ Hibernate-mapping-3.0.dtd ">
Order.hbm.xml
<?xml version= "1.0"? ><! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en" "http://hibernate.sourceforge.net/ Hibernate-mapping-3.0.dtd ">Package Com.atguigu.hibernate.strategy;import Java.util.list;import Org.hibernate.hibernate;import Org.hibernate.session;import Org.hibernate.sessionfactory;import Org.hibernate.transaction;import Org.hibernate.cfg.configuration;import Org.hibernate.service.serviceregistry;import Org.hibernate.service.serviceregistrybuilder;import Org.junit.after;import Org.junit.before;import Org.junit.Test ;p Ublic class Hibernatetest {private sessionfactory sessionfactory;private Session session;private Transaction transaction; @Beforepublic void init () {Configuration configuration = new Configuration (). Configure (); Serviceregistry serviceregistry = new Serviceregistrybuilder (). Applysettings (Configuration.getproperties ()) . Buildserviceregistry (); sessionfactory = Configuration.buildsessionfactory (serviceregistry); session = Session Factory.opensession (); transaction = Session.begintransaction ();} @Afterpublic void Destroy () {transaction.commit (); Session.close (); Sessionfactory.close ();} @Testpublic void Testmany2onestrategy () {//order Order = (order) Session.get (Order.class, 1);//system.out.println ( Order.getcustomer (). Getcustomername ()); list<order> orders = Session.createquery ("from Order o"). List (), for (Order order:orders) {if (Order.getcustomer () ! = null) {System.out.println (Order.getcustomer (). Getcustomername ());}} 1. A lazy value of proxy and false represents the corresponding attribute using deferred retrieval and immediate retrieval of//2. The fetch value is join, which represents the property//ignoring the Lazy property on the one end of the 1 associated with an urgent left outer join. 3. Batch-size, this property needs to be set at the 1 end of the class element://<class name= "Customer" table= "CUSTOMERS" lazy= "true" batch-size= "5" >//effect: The number of proxy objects that initialized 1 at a time. } @Testpublic void TestSetFetch2 () {Customer customer = (customer) session.get (Customer.class, 1); System.out.println (Customer.getorders (). Size ()); } @Testpublic void Testsetfetch () {list<customer> customers = Session.createquery ("from Customer"). List (); System.out.println (Customers.size ()); for (Customer customer:customers) {if (customer.getorders () = null) System.out.println (Customer.getordeRS (). Size ()); Fetch property of the Set collection: Determines how the Orders collection is initialized. 1. The default value is select. Initializes the set element//2 in a normal way. You can take a value of subselect. All set sets are initialized by a subquery. Subquery//occurs as the in condition of the WHERE clause, and the subquery queries all 1 IDs at one end. The lazy is valid at this time.//But batch-size fails. 3. If the value is join. //3.1, when loading an object at one end of 1, retrieves the collection property of one end of N using an urgent left outer join (querying with a left outer link and initializing the collection property)//3.2 ignores the Lazy property.//3.3 HQL query ignores Fetch=join value} @Tes tpublic void Testsetbatchsize () {list<customer> customers = Session.createquery ("from Customer"). List (); System.out.println (Customers.size ()); for (Customer customer:customers) {if (customer.getorders () = null) System.out.println (Customer.getorders (). Size ());} The Batch-size property of the Set element: Sets the number of initialized set sets at one time. } @Testpublic void Testone2manylevelstrategy () {Customer customer = (customer) session.get (Customer.class, 1); System.out.println (Customer.getcustomername ()); System.out.println (Customer.getorders (). Size ()); Order order = New Order (); Order.setorderid (1); System.out.println (Customer.getorders (). Contains (order)); Hibernate.initialize (Customer.getordERS ()); ---------------The Lazy property of set------------------//1. The 1-n or N-n collection property defaults to the lazy load retrieval policy.//2. You can modify the default retrieval policy by setting the lazy property of the set. The default is true//and is not recommended to be set to false. 3. Lazy can also be set to extra. Enhanced deferred retrieval. This value will delay the collection initialization whenever possible!} @Testpublic void Testclasslevelstrategy () {Customer customer = (customer) session.load (Customer.class, 1); System.out.println (Customer.getclass ()); System.out.println (Customer.getcustomerid ()); System.out.println (Customer.getcustomername ()); }}