This article describes the concept of a one-level, two-level cache in Hibernate and how to use it.
First, the outline
2. What is a first-level cache
3. First-level cache example Display
4. Level Two cache and sample display
5. Summary
Second, what is a first-level cache
In Hibernate, the so-called first-level cache is the session object, but a primary cache is not much of a function to improve performance, and the main purpose of the session is to manage the state of the entity object (temporary, offline, persistent).
Its cache model is as follows:
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M00/5A/19/wKioL1T2q6Dj17f2AADNrUi4H4E838.jpg "title=" 1.png " alt= "Wkiol1t2q6dj17f2aadnrui4h4e838.jpg"/>
三、一级 Cache Example
3.1 Queries (get,load, HQL)
3.1.1 Get/load method
@Testpublic void Testget () {Session session = Factory.opensession (); Transaction tx = Session.begintransaction (); Tx.begin ();//First query User user1 = (user) Session.get (user.class, 1); System.out.println (user1);//If there is a id=1 User object cache in the session, you will not need to perform sqluser user2 = (user) Session.get when querying again (User.class, 1); System.out.println (User2); Tx.commit (); Session.close ();}
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M00/5A/1D/wKiom1T2rJbygcCbAACxs-skg8A162.jpg "title=" 2.png " alt= "Wkiom1t2rjbygccbaacxs-skg8a162.jpg"/>
If the second query is executed after the session is closed, an exception is thrown and the session is closed. The Load method type, except that it supports lazy loading queries.
3.1.2 HQL Query
@Testpublic void testhqlqueryfromcache () throws Exception {session session = factory.opensession (); Transaction tx = session.begintransaction (); Tx.begin ();// uses HQL to query the Id=1 user object, which will id= 1 of objects are written to the session cache user user1 = (User) session.createquery ("From user where id = 1 "). Uniqueresult (); System.out.println (user1); System.out.println ("================");// performs the second same query, by default the Id=1 object cannot be obtained from the session, but the Id=1 object is also written to the user in the session cache. user2 = (User) session.createquery ("From user where id = 1"). Uniqueresult (); System.out.println (User2); System.out.println ("================");// uses the Get method query, because id=1 objects already exist in the session, they will not execute sqluser user3 = (User) session.get (user.class, 1); System.out.println (User3); Tx.commit (); Session.close ();}
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M01/5A/1D/wKiom1T2ryGC0cNdAAGJUGCGiPM791.jpg "title=" 3.png " alt= "Wkiom1t2rygc0cndaagjugcgipm791.jpg"/>
The effect of 3.2 Update/delete on the session
After the session executes the query, if the update or delete operation is performed at this time, will the data in the session change? This is demonstrated by the following example:
@Testpublic void testupdate () {Session session = factory.opensession (); Transaction tx = session.begintransaction (); Tx.begin ();// performs a query operation that stores the id=1 data in the session user user = (user) Session.get (user.class, 1); System.out.println (user);// perform the UPDATE operation to modify the id=1 data session.createquery ("Update user set name = ? where id = 1 "). Setparameter (0, " Updateordelete "). ExecuteUpdate ();// If the update operation is performed, the entity Name property in session is modified, then the Updateordelete value is obtained, otherwise the user user2 = (User) is persisted. Session.get (user.class, 1); System.out.println (User2); Tx.commit (); Session.close ();}
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M01/5A/1A/wKioL1T2tVnD1IBDAAG-cMRXvbc859.jpg "title=" 4.png " alt= "Wkiol1t2tvnd1ibdaag-cmrxvbc859.jpg"/> concludes that update or delete (which does not show the delete operation) does not modify the current session data. You can only wait for the next session query, or manually refresh session data using Session.refresh ()/clear.
四、二级 cache and Sample display
4.1 What is a level two cache
A secondary cache actually provides a common data cache to improve query performance, and when the real-time requirements for data are very high, there is no need to use level two caching, and the two-level cache model is as follows:
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M02/5A/1A/wKioL1T2t1XDXfLRAADN_jqhGZo652.jpg "title=" 5.png " alt= "Wkiol1t2t1xdxflraadn_jqhgzo652.jpg"/> can be understood as two-level cache is a different session of shared data, and the first-level cache is for the same session operation.
4.2 Configuring Level Two caching
Hibernate does not use a level two cache by default, and if used, it needs to be configured with some parameters.
1, configure the Level two cache type (provider) "Hibernate.cfg.xml Configuration"
<property name= "Hibernate.cache.provider_class" >org.hibernate.cache.hashtablecacheprovider</property >
2. Set up entity classes, collections, and query conditions that need to be configured
<!--open Query cache--><property name= "Hibernate.cache.use_query_cache" >true</property><!--entity class-- <class-cache usage= "Read-write" class= "Com.hibernate.seconde_cache. User "/><!--Note: can also be configured in the entity mapping file <cache> not introduced here--
4.3 Various types of cache handling
Some basic two-level cache configurations are shown roughly in 4.2, and in this section there are three main scenarios for a two-level cache configuration.
4.3.1 single Entity level two cache
1) configuration
<!--set cache provider--><property name= "Hibernate.cache.provider_class" > org.hibernate.cache.hashtablecacheprovider</property><!--entity class--><class-cache usage= "Read-write" Class= "Com.hibernate.seconde_cache. User "/>
2) Sample Show
@Testpublic void Testsingleentity () throws Exception {//first session, storing data session Session1 = Factory.opensession (); Transaction tx1 = Session1.begintransaction (); Tx1.begin (); User User1 = (user) Session1.get (user.class, 1); System.out.println (user1); Tx1.commit (); Session1.close (); System.out.println ("\n===================\n");//The second session reads the first session data session Session2 = Factory.opensession () ; Transaction tx2 = Session2.begintransaction (); Tx2.begin (); User User2 = (user) Session2.get (user.class, 1); System.out.println (User2); Tx2.commit (); Session2.close ();}
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M00/5A/1E/wKiom1T2uVOQYuqQAAEMb6Y-nJI332.jpg "title=" 6.png " alt= "Wkiom1t2uvoqyuqqaaemb6y-nji332.jpg"/>
3) The effect of update and delete on level two caching
@Testpublic void testsingleentityofupdate () throws Exception {// first session, Storage data session session1 = factory.opensession (); Transaction tx1 = session1.begintransaction (); Tx1.begin (); user user1 = (User) session1.get (user.class, 1); System.out.println (user1); Tx1.commit (); Session1.close (); System.out.println ("\n===================\n"); Session updatesession = factory.opensession (); Updatesession.createquery ("UPDATE User Set name=? where id = 1 "). Setparameter (0, " Second cache "). ExecuteUpdate (); System.out.println ("\n===================\n");// the second session reads the data from the first session session session2 = factory.opensession (); Transaction tx2 = session2.begintransaction (); Tx2.begin (); user user2 = (User) session2.get (user.class, 1); System.out.println (User2); Tx2.commit (); Session2.close ();}
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M01/5A/1E/wKiom1T2umXDNnb5AAFSZ30FCHs482.jpg "title=" 7.png " alt= "Wkiom1t2umxdnnb5aafsz30fchs482.jpg"/>
This allows you to update and delete operations, even if you affect the level two cache operation, the other session can be found in time
4.3.2 Query Condition Cache
Before describing how to cache query conditions, how to implement caching through hibernate-provided methods and explain the undesirable effects of this method, and how the query criteria are cached.
1) Non-query condition implementation cache (cache configuration with 4.3.1)
Execute the same query condition using list, and still execute SQL repeatedly
@Testpublic void Testhql () throws Exception {//first session, storing data session Session1 = Factory.opensession (); Transaction tx1 = Session1.begintransaction (); Tx1.begin (); List user1= session1.createquery ("from User"). List (); System.out.println (user1); Tx1.commit (); Session1.close (); System.out.println ("\n===================\n");//The second session reads the first session data session Session2 = Factory.opensession () ; Transaction tx2 = Session2.begintransaction (); Tx2.begin (); List user2 = Session2.createquery ("from User"). List (); System.out.println (User2); Tx2.commit (); Session2.close ();}
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M01/5A/1E/wKiom1T2vBehJ8YoAAEkYBSwwkI287.jpg "title=" 8.png " alt= "Wkiom1t2vbehj8yoaaekybswwki287.jpg"/>
Use the iterate method instead of the list method, but n+1 this query problem, query the ID that matches the condition, and then query by ID.
@Testpublic void Testhqlofiterate () throws Exception {Session session1 = factory.opensession (); Transaction tx1 = session1.begintransaction () tx1.begin ();//Use the iterate method instead of the list method iterator<user> users1= Session1.createquery ("from User"). Iterate (), while (Users1.hasnext ()) {System.out.println (Users1.next ());} Tx1.commit (); Session1.close (); System.out.println ("\n===================\n"); Session Session2 = Factory.opensession (); Transaction tx2 = Session2.begintransaction (); Tx2.begin ();iterator<user> users2= session2.createquery ("from User "). Iterate (); while (Users2.hasnext ()) {System.out.println (Users2.next ());} Tx2.commit (); Session2.close ();}
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M02/5A/1A/wKioL1T2vmTDcEIOAALQhZVIN7w459.jpg "title=" 9.png " alt= "Wkiol1t2vmtdceioaalqhzvin7w459.jpg"/>
2) using the query criteria cache
The configuration needs to be added compared to 4.3.1:
<!--open Query cache--><property name= "Hibernate.cache.use_query_cache" >true</property>
In the case of 1), the number of queries in the query condition filter can be reduced by 1, which greatly improves the query efficiency:
@Testpublic void testhqlofcondition () throws Exception {session session1 = factory.opensession (); Transaction tx1 = session1.begintransaction (); Tx1.begin ();// by executing the setcacheable (true) method, Indicates that the query condition is cached// that is, stored as key from use where id < 4, value: The result set of the corresponding query list list1= Session1.createquery ("From user where id < 4"). Setcacheable (True). List (); System.out.println (List1); Tx1.commit (); Session1.close (); System.out.println ("\n===================\n"); Session session2 = factory.opensession (); Transaction tx2 = session2.begintransaction (); Tx2.begin (); List list2= session2.createquery ("From user where id < 4"). SetCacheable ( true). List (); System.out.println (List2); Tx2.commit (); Session2.close ();}
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M02/5A/1E/wKiom1T2vzuAmY9BAAEmNPts5cE903.jpg "title=" 10.png "alt=" Wkiom1t2vzuamy9baaemnpts5ce903.jpg "/>
Note: The query criteria must remain constant, otherwise it will be considered as a different query condition. The delete and update operations are consistent with 4.3.1 and do not show results here.
4.3.3 Collection element Query cache display
The sample entity Mapping model is (class, student Way "Many-to-1 relationship"), the specific mapping code, entity class code is not shown here.
1) configuration (add the following configuration compared to 4.3.1)
<!--Configure class entity cache--><class-cache usage= "Read-write" class= "Com.hibernate.seconde_cache. Classes "/><!--Configure student entity cache--><class-cache usage=" Read-write "class=" Com.hibernate.seconde_cache. Student "/><!--Configure the Student collection cache in the class, notice that the class is fully qualified. Property name--><collection-cache usage=" Read-write "collection=" Com.hibernate.seconde_cache. Classes.students "/>
2) Code example:
@Testpublic void testset () throws exception { Session session1 = factory.opensession (); Transaction tx1 = session1.begintransaction (); Tx1.begin ();// Query id=1 class classes classes1 = (Classes) session1.get (classes.class, 1); System.out.println (classes1);// performs lazy loading to get data, and if you want to cache the collection elements, you must add the collection configuration System.out.println (Classes1.getstudents () ); Tx1.commit (); Session1.close (); System.out.println ("\n===================\n"); Session session2 = factory.opensession (); Transaction tx2 = session2.begintransaction (); Tx2.begin ();// The second session, get the data in level two cache classes classes2 = (Classes) session2.get (classes.class, 1); System.out.println (Classes2); System.out.println (Classes2.getstudents ()); Tx2.commit (); Session2.close ();}
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M01/5A/1B/wKioL1T2xy3hVEk_AAHkZTHeS5o529.jpg "title=" 11.png "alt=" Wkiol1t2xy3hvek_aahkzthes5o529.jpg "/>
If you do not add
<collection-cache usage= "Read-write" collection= "Com.hibernate.seconde_cache. Classes.students "/>
Then the following results will appear:
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M01/5A/1F/wKiom1T2xqHCaM1yAAJTUt4-NXw345.jpg "title=" 12.png "alt=" Wkiom1t2xqhcam1yaajtut4-nxw345.jpg "/>
V. Summary
The level two cache knowledge involved is far more than this article, and generally does not use the Hashtable provider in this article, usually using:
650) this.width=650; "src=" http://s3.51cto.com/wyfs02/M00/5A/1F/wKiom1T2x4LTRU8cAAJa2dvolCI367.jpg "title=" 13.png "alt=" Wkiom1t2x4ltru8caaja2dvolci367.jpg "/>
Level 1 caching is a must, because any operation needs to use the session, but it has little impact on performance improvement, and the level two cache for those who do not have high data real-time and accuracy requirements, it is recommended to improve query performance.
This article is from the "Java Program Ghost" blog, please be sure to keep this source http://793404905.blog.51cto.com/6179428/1617287
"Hibernate" level, level two cache