Turn from:
Http://www.blogjava.net/RoyPayne/archive/2012/01/30/369017.html
http://msi110.iteye.com/blog/710183
http://blog.csdn.net/xiaoxian8023/article/details/15380529
========================================================
stored in the session cache is a graph of interrelated objects. By default, when Hibernate loads the customer object from the database, all associated order objects are loaded together. Take the customer and order classes as an example, assuming that the customer_id foreign key of the Orders table is allowed to be null
The Find () method of the following session is used to retrieve all the customer objects in the database:
When you run the Find () method above, hibernate queries all the records in the Customers table, and then, based on the ID of each record, queries the records for referential relationships in the Orders table, and Hibernate executes the following SELECT statements in turn:
Select * fromCUSTOMERS;Select * fromORDERSwherecustomer_id=1; Select * fromORDERSwherecustomer_id=2; Select * fromORDERSwherecustomer_id=3; Select * fromORDERSwherecustomer_id=4;
With the above 5 SELECT statements, Hibernate finally loads 4 customer objects and 5 order objects, forming an associated object graph in memory.
Hibernate uses the default immediate retrieval policy when retrieving the order object associated with the customer. There are two major deficiencies in this search strategy:
(1) The number of SELECT statements is too large and requires frequent access to the database, which can affect retrieval performance. If you need to query n customer objects, you must execute the n+1 select query statement. This is the classic n+1 times select query problem. This retrieval strategy does not take advantage of SQL's connection query functionality, such as the 5 SELECT statements above can be completed by the following 1 SELECT statements:
SELECT * FROM CUSTOMERS left outer join ORDERS on Customers.id
The SELECT statement above uses the SQL LEFT OUTER join query feature to query all records of the Customers table in a SELECT statement, as well as the records of the matching Orders table.
(2) In the case where the application logic only needs to access the customer object and does not need to access the order object, loading the order object is a completely redundant operation, and these extra order objects waste a lot of memory space.
In order to solve the above problems,hibernate provides two other retrieval strategies: Deferred retrieval strategy and urgent left outer connection retrieval strategy. The deferred retrieval strategy avoids the unnecessary loading of the associated objects that the application does not need to access, and the urgent left outer connection retrieval strategy takes full advantage of SQL's outer join query capability and can reduce the number of SELECT statements.
For database access or to have to consider performance issues, after setting the 1-to-many relationship, the query will appear in the legendary n + 1 problem.
1) 1-to-many, in 1-side, find the N objects, then need to have n objects associated with the collection, so the original SQL query becomes n + 1 bar
2) Many to 1, in the multi-party, the query gets the M object, then will also be the M object corresponding to the 1-side object out, also become m+1
How to solve the N + 1 problem?
1) Lazy=true, Hibernate3 started by default is Lazy=true, Lazy=true will not immediately query the association object, only if you need to associate an object (access its properties, not the ID field) will occur only when the query action.
2) Level two cache, in object update, delete, add compared to the query is much less, two-level cache application will not be afraid of the N + 1 problem, because even if the first query is slow, then the direct cache hit is very fast.
Different solutions, different ideas, the second one is just the use of n +1.
3) Of course you can also set Fetch=join (annotation: @ManyToOne () @Fetch (Fetchmode.join))
Hibernate n+1 Problems