What is deferred loading?
Lazy loading is when an application wants to get an object from the database (without setting the Lazy property value to false), hibernate simply gets the OID of the qualifying object from the database and generates the proxy object without loading the object
The corresponding value is loaded when the property of the object is Accessed. The simple answer is to reduce the amount of data that is queried as much as Possible.
How to configure lazy loading
The lazy attribute in the. hbm configuration file is accompanied by a value in hibernate, and the lazy attribute appears in a different position than its function and Value. The following is a detailed description of the different values and effects in different locations
lazy in the class tag:
The lazy values that appear in the class tag class are true (the default is lazy loading), false (load now), and both are as Follows:
If lazy evaluates to false, all property values (without custom type properties) are loaded immediately when the application fetches the object from the database
take the employee table as an example test case is as Follows:
Employee Table Structure:
Employee Entity Class:
HBM mapping file for employee tables:
Test code:
Test Results:
From the results we can see that the EMP object is not loaded with deferred loading but the referenced property of its Save department (Dept) object is not Loaded.
Let's take a look at the result when the value of the Lazy property is True
From what we can see, the properties of lazy, whether true or false, have the same result! What is this for? Is the value of the lazy property true whether it should be delayed loading?
Note: we get the Get method for the employee object when we write the test case above, and I said in my previous blog that the Get method of the session object does not support lazy loading he ignores the class-level lazily attribute! Let's replace the Get method with the Load method to test it.
From this we can see that when the value of the Lazy property is true, hibernate does not load all of the property values at once, and only when the program needs to load to reduce the burden on the database interaction and improve the performance of the program, which is also the purpose of lazy loading!
Lazy in a many-to-one association
If you want to load the custom type property associated with it immediately while getting the object, you need to set the Lazy property in its Many-to-one configuration, where the value of the Lazy property is: proxy: lazy load (default), no-proxy: agentless lazy load, false: Load now
For example, We add the Lazy property value to false on the basis of instance one to Test:
the Lazy property in the Set element
We know that if a collection of other entities exists in an object, the set element needs to be configured in the HBM file for mapping between the tables, and the lazy property can be added to the set element with the value: true: lazy load (default), false: load now, extra: enhance delay loading.
Here the value of false is no longer tested primarily to test the difference between true and Extra. We then introduce the Dept (department) class on the basis of example one to Test:
Department entity Class :
Departmental Table Mapping File:
Test code:
The Lazy property value is true:
The value of the Lazy property is Extra:
no session problems caused by delayed loading
When we write a layered-based b/s program, we often throw the no session exception because the session is closed prematurely and the data is not loaded:
The reason for this exception is that the code for the Same-city operational data is written on the DAO and biz tiers But these two layers are not responsible for the presentation of the data and when we present the data in the JSP page, the session is closed and the relational data with the deferred load is not loaded into the Object. When the JSP page accesses the object properties, hibernate attempts to use the session object to interact with the database and discovers that there are no available session objects to throw the Exception.
For such problems the same city practice is to use filters (filter) to store the session object in the presentation Layer. Create the filter as shown in the following code:
Then configure the filter in the Web. XML file:
After the above operation can solve the problem of no Session. Of course there are other solutions, but this solution is the most used and more complete solution,
Cache
Definition of Cache
The cache is designed to reduce the number of application and database interactions and to create a space for a small amount of non-critical data that is less frequently modified and often queried. is a certain range of space in exchange for users to query data from the database speed and performance of a solution!
typically, the cache is divided into the following categories:
Internal cache, Level Two cache, query cache, and Third-party cache Implementations.
Internal Cache
In hibernate, the internal cache, also known as primary cache and transaction level caching, is automatically maintained by Hibernate and cannot be uninstalled. Its life cycle is the same as the lifetime of the session object, and the cache is automatically reclaimed when the session is Closed. As shown Below:
The results of the operation are as Follows:
From the results we can find that two times when querying a database hibernate value is generating an SQL statement that is only the first time the query and the database are Interacting. And put the queried object into the internal cache when hibernate discovers that the object already exists in the internal cache in the second query, it simply returns the object and does not interact with the database, and the memory address of the object for the two queries is exactly the Same. This allows you to draw a reference to the memory address of the object that is cached in the internal cache instead of the Object's individual property values!
Level Two cache
The secondary cache is a configurable plug-in, a process or cluster-wide cache that can be shared by all sessions
configuration of Level two cache
There are many plugins that configure level two caching in hibernate the following example uses the Ehcache plug-in to configure a level two Cache.
1. Introduce the following Jar Package.
Ehcache-1.2.3.jar Core Library
Backport-util-concurrent.jar
Commons-logging.jar
2. Configure Hibernate.cfg.xml to turn on level two cache
<propertyname="hibernate.cache.use_second_level_cache">true</property>
3. Configure the vendor for level two cache
<property name="hibernate.cache.provider_class">org.hibernate.cache.ehcacheprovider</property >
Note: the property element must be above the mapping element
4. Configure classes that can enter level two cache
<class-cache usage="read-write" class= "Cn.happy.entity. EMP "/>
5. Introduction of Ehcache.xml files in the Classpath directory
After the above 5 steps, you can put the Dept object into the level two cache, write the test case below
Test Results:
From the results we can open the second query department and did not generate a generated SQL statement but the object we printed two times is not the same memory address, This is because the Two-level cache is not a reference to the memory address of the Object's image, but the bulk attribute of the object (which can be thought of as the individual property values of the object), so we need to re-assemble these bulk properties into a complete object in memory when we access level Two. If you look closely you will find that Hibernate still generates SQL statements the second time we visit the employee Collection. That's because the above level two cache is configured for Class-level targeting. If you want to cache an employee collection, you will need to include the collection cache configuration in the Hibernate.cfg.xml configuration file, as Follows:
Note: This configuration must be the next element of the mapping element
Then we'll run the test again to get the results as Follows:
You might be surprised when you see the Results. when the collection cache he only generates an SQL statement how did I become two SQL after I'm done with my company? But you notice that the two SQL statements are exactly the same, based on the OID of the employee object! So where does the OID of the employee object come from? yes, That's What you get from the level two cache. as to why only the OID of the employee object is cached and no other property value is cached, It is because the employee object is not configured with a level two cache, it cannot enter a level two cache, and there is no way to get its other property values from the two cache, we will test the employee object after configuring
The results are as follows:
Query Cache
configuration of the query cache
Add the above elements to the Hibernate.cfg.xml configuration file to turn on level two caching. And you must call Query1.setcacheable (true) before fetching the collection when using query for caching;
Write the test cases below to Test:
Test Results:
Attention:
1. The query cache is based on a level two cache and must be configured with a level two cache when configuring the query cache otherwise the following exception will be thrown
2. A reference to an Object's memory address is saved in the query cache instead of the bulk property of the Object.
3. The query cache is based on whether the SQL statement generated by the TWO-HQL query statement after hibernate internal conversion remains the same as deciding whether to interact with the database instead of the OID based on its object, such as the following test case although the same object is queried for the same oid, but still interacts with the database!
Test Results:
deferred loading and caching legacy issues
the lazy attribute and the Fetch attribute are
In a one-to-many or Many-to-many retrieval strategy determined by lazy and fetch, lazy: determines the timing of association object initialization, Fetch: determines the form of SQL statement Construction. Fetch attributes Are: Join: urgent left outer join, Select: multiple simple SQL (default), subselect: subquery. When the Fetch attribute value is join, The Lazy property is ignored with an immediate load policy. For example, a department with a socialize number of 5, even if the lazy attribute in the set element that maps the employee collection in the departmental mapping file is set to TRUE or extra immediately loads a collection of all employees under that department, the SQL statements generated internally by Hibernate are as Follows:
the difference between the list method and the iterate method of the query interface
1. The returned type is different, the list returns List,iterate returns iterator,
2. The way to get the data is not the same, the list will directly check the database, iterate will go to the database to remove the id, and then really want to traverse an object first to the cache to find, if not found, the ID is the condition to send a SQL to the database, so that if there is no data in the cache, The number of times the database is queried is n+1.
3.iterate queries the level 2 cache, and list caches only, but does not use the cache (unless the query cache is combined).
Each object in the list returned in 4.list is the original object, and the object returned in iterate is the proxy object
cached internal storage implementations
1. Object data in the cache, in the form of a map collection
2. Both the First-level cache and the Two-level cache are key values that are combined with the OID of the object as the map, and the query cache is the SQL statement generated internally by hibernate as the key value
3. The value values of the Map collection in the First-level cache and the query cache hold a reference to the memory object, while the Two-level cache holds the Object's bulk Properties.
4. When an application needs to fetch data from a database, hibernate retrieves the First-level cache or query cache > Level two cache, or whether there are qualifying data in the query cache if there is a direct return that no longer interacts with the Database. conversely, generate SQL statements to interact with the database to get the corresponding data and then return and put the data into a cache > level two cache or query cache
saving a level two cache to a hard disk
The Path property value of the Diskstore element in the Ehcache.xml configuration file under the Classpath directory is set to the path that you want to save and the Maxelementsinmemory property value in the cache element is set to 0.
Lazy loading and caching in Hibernate