First, Introduction
The session's cache can hold objects that are related to each other. When hibernate loads an object from a database, all objects associated with it are automatically loaded, and the associated objects waste a lot of memory space. And we can set the retrieval policy to optimize the retrieval performance.
Hibernate offers three different retrieval strategies
-Retrieve policy immediately: Loads the object and associated objects as soon as the object is retrieved. -Deferred retrieval policy: objects and associated objects are loaded only when they are used. To avoid unnecessary loading of unwanted objects.
second, class-level retrieval Strategy
Example:
Let's do a small example of the Load method plus the breakpoint public class Demo { private session session; @Test public void Test () { //Read config file configuration conf=new configuration (). Configure (); Create Factory sessionfactory Sessionfactory=conf.buildsessionfactory () based on configuration; Session = Sessionfactory.opensession (); Transaction ts=session.begintransaction (); Customer C=session.load (Customer.class, 7);//Here Add a breakpoint to observe the effect System.out.println (C.getname ()); Ts.commit (); Session.close (); Sessionfactory.close (); } } When the Lazy property is true, the call to the Load method does not output anything, and the SELECT statement is output when the object is used. When the lazy property is false, calling the Load method outputs the SELECT statement directly.
Principle:
When a policy is deferred, the Load method is executed, which returns the proxy object of the current object, which is dynamically generated by hibernate.
The proxy object inherits the current object, initializes only the OID property, and all other properties are null when the program accesses the proxy class property.
Hibernate initializes the proxy object, the initialization process executes the SELECT statement, and all the data is loaded from the database.
three or one policy policies for multiple association levels
Association level Retrieval Policy: When you query an object that is associated with a relationship, whether the associated object needs to be loaded when the object is loaded.
In the mapping file, use the < set > element to configure a one-to-many or many-to-many association relationship.
The lazy and fetch properties in the < set > element determine the load policy.
Lazy properties: Consistent with class-level loading policies. The default value is true. Even with deferred retrieval. When lazy is false, it is used for immediate retrieval.
Example:
public class Demo {private session session; @Test public void Test () {//Read configuration file config conf=new Configurat Ion (). Configure (); Create Factory Sessionfactory Sessionfactory=conf.buildsessionfactory () based on configuration; Session = Sessionfactory.opensession (); Transaction ts=session.begintransaction (); Load Customer Object customer c= (customer) Session.get (Customer.class, 7); Load the customer associated order object for (Order O:c.getorders ()) {System.out.println (O.getnam E ()); } ts.commit (); Session.close (); Sessionfactory.close (); When our lazy property is false, when we execute the GET method, we use the immediate retrieval policy, which executes two SELECT statements, loading the customer and the associated orders collection. When our lazy property is true, the Get method executes only one sentence SeleCT statement, when the orders property of the customer refers to a collection proxy class that is not initialized, there is no order object in the Orders collection, and when we use order, the collection proxy class is initialized to retrieve all the associated order objects in the database
Fetch property: Determines the format of the query statement when the collection is loaded. The values are: SELECT, Subselect, join Select: (default) query using a normal SELECT statement. Subselect: Uses a subquery to load collection data. Useful when locating multiple objects, such as finding multiple users, each with multiple order joins: Query with an urgent left outer connection retrieval policy. The Fetch property set to the Join,lazy property is ignored, and the object associated with it is bound to be loaded when the object is queried.
Example:
public class Demo {private session session; @Test public void Test () {//Read config file configuration Conf=new Configuration (). Configure (); Create Factory Sessionfactory Sessionfactory=conf.buildsessionfactory () based on configuration; Session = Sessionfactory.opensession (); Transaction ts=session.begintransaction (); Load Customer Object customer c= (customer) Session.get (Customer.class, 7); Loads the associated Order object for (Order O:c.getorders ()) {System.out.println (O.getnam E ()); } ts.commit (); Session.close (); Sessionfactory.close (); } }
When the Fetch property is the default value (select), the printed SQL statement Hibernate: select customer0_.id as id1_0_0_, Customer0_.name as name2_0_0_ from customer customer0_ where customer0_.id=? Hibernate: Select orders0_.cid as cid3_1_0_, orders0_.id as id1_1_0_, orders0_.id as id1_1_1_, Orders0_.name as name2_1_1_, Orders0_.cid as cid3_1_1_ from orders orders0_ where Orders0_.cid=?
When the fetch attribute is join, print the SELECT statement, using the left OUTER JOIN query statement, to reduce the SELECT statement Hibernate: select customer0_.id as id1_0_0_, Customer0_.name as name2_0_0_, orders1_.cid as cid3_1_1_, orders1_.id as id1_1_1_, orders1_.id as Id1_1_2_ , Orders1_.name as name2_1_2_, Orders1_.cid as cid3_1_2_ from customer customer0_ left outer Join orders orders1_ on customer0_.id=orders1_.cid where customer0_.id=?
When the Fetch property is subselect, we query all the customer and then use each customer's orders collection public class Demo {private Ses Sion session; @Test public void Test () {//Read configuration file config conf=new Configurat Ion (). Configure (); Create Factory Sessionfactory Sessionfactory=conf.buildsessionfactory () based on configuration; Session = Sessionfactory.opensession (); Transaction ts=session.begintransaction (); Find all customer list<customer> customerlist=session.createquery ("from Customer"). List (); Load each customer associated orders collection for (Customer c:customerlist) {System.out. println (C.getorders (). Size ()); } ts.commit (); Session.close (); Sessionfactory.close (); } }
printed statements, using subquery statements when the Fetch property is Subselect, Hibernate is able to pass the select language with a subquery To initialize an instance of a collection of multiple objects in a full batch. Hibernate:select customer0_.id as id1_0_, customer0_.na Me as name2_0_ from Customer customer0_ Hibernate: Select Orders0_.cid as cid3_1_1_, orders0_.id as id1_1_1_, Orders0_.id as id1_1_0_, orders0_.name as name2_1_0_, orders0_. CID as cid3_1_0_ from orders orders0_ where Orders0_.cid in (select Customer0_.id From customer customer0_)
Fetch and lazy combination
iv. policy policies for multiple-to-one association levels
As with the <set> element, the,<many-to-one> element also has the lazy and fetch attributes. the optional value of lazy has false (retrieve now), Proxy (deferred retrieval), No-proxy (no agent deferred retrieval) Fetch attribute optional value is select and join
Example: Set the order profile in the Fetch attribute to join public class Demo { private session session; @Test public void Test () { //Read config file configuration conf=new configuration (). Configure (); Create Factory sessionfactory Sessionfactory=conf.buildsessionfactory () based on configuration; Session = Sessionfactory.opensession (); Transaction ts=session.begintransaction (); Load Order Object Order c= (Order) Session.get (Order.class, 6); Loads the associated customer object System.out.println (C.getcustomer (). GetName ()); Ts.commit (); Session.close (); Sessionfactory.close (); } }
When you execute the GET method, the outer join query is used directly. Ignore lazy. Hibernate: select order0_.id as id1_1_0_, order0_.name as name2_1_0_, order0_.cid as cid3_1_0_, customer1_.id as id1_0_1_, Customer1_.name as name2_0_1_ from orders order0_ left outer JOIN customer customer1_ on order0_.cid=customer1_.id where order0_.id=?
Five, bulk search
The < class > and < set > elements contain the Batch-size property. Sets the number of bulk searches. The optional value is a positive integer, which defaults to 1.
For immediate retrieval and bulk retrieval at the association level only
We set up bulk delay retrieval in the customer profile <set name= "Orders" lazy= "true" batch-size= "3" > public class Demo { Private session session; @Test public void Test () {//Read configuration file config conf=new Configurat Ion (). Configure (); Create Factory Sessionfactory Sessionfactory=conf.buildsessionfactory () based on configuration; Session = Sessionfactory.opensession (); Transaction ts=session.begintransaction (); Load all Customer objects list<customer> customerlist=session.createquery ("from Customer"). List (); for (Customer c:customerlist) {System.out.println (C.getorders (). Size ()); } ts.commit (); Session.close (); Sessionfactory.close (); } }
We use deferred retrieval, and when we use orders for each customer, we load orders and print a SELECT statement each time a loop is executed. If there are many customer objects, then a lot of SELECT statements are printed. so we can use bulk search. You only need to set the Batch-size property of <set> to 3. So the three orders collection is initialized in bulk, using the in statement. This will not send the statement when the collection of the first second third object is used.
(11) Hibernate's retrieval strategy