Detailed Java Hibernate framework cache and level two cache _java

Source: Internet
Author: User
Tags sessions

Cache

Today we'll talk about the entity state and the hibernate cache in Hibernate.
1 First, let's take a look at the entity state:
The entity state is mainly divided into three kinds: transient,persitent,detached.
Read English should probably understand it.
Transient: It means that the data does not correspond to the data in the database.
Persistent: means that the data corresponds to the data in the database, and any changes to it will be reflected in the database.
Detached: means the data corresponds to the data in the database, but its modifications do not affect the database's records because the session is closed.
Below we direct code to:

Transaction tx = Session.begintransaction (); 
User user = new user (); 
User.setname ("Shun"); 
The user has not been saved to the database, the database table does not have the corresponding record, it is transient state 
session.save (user); 
Tx.commit (); 
After submission, user becomes persistent state 
session.close (); 
Because session is closed, the user is detached state, and all of its modifications are not reflected in the database. Session 
     
Session2 = Sessionfactory.opensession (); 
tx = Session2.begintransaction (); 
User.setname ("shun123"); 
Session2.saveorupdate (user); 
Tx.commit (); 
When we call Saveorupdate, the user reverts to the persistent state, and all of its modifications are reflected in the database. 
Session2.close (); 

   We see code, first we define an object user, which is a transient state before it is saved, and there is no corresponding record in the database. And when we save and submit the changes, user becomes the persistent state, with a corresponding record in the database. When we close the session, user becomes the detached state, and its changes are not reflected in the database unless we manually invoke the corresponding update and add methods such as Saveorupdate. And when we directly want it from persistent to transient state, how to do? Delete directly on it, delete the object in the database does not have a corresponding record, also become transient state.
 
 hibernate state transitions are relatively simple, and when the state is transient, the database has no records, and persistent and detached have corresponding records. But the only difference is that the detached is in the state after the session is closed. So what is the difference between transient and detached? Is that there is no database table to record the corresponding problem.
 
 2) look at the state. Hibernate cache
 hibernate cache is divided into two types, first-level cache, and level two cache.
  Level caching: the so-called first-level cache is the internal cache.
  Level Two cache: it includes application-level caching, in Hibernate is called Sessionfactory cache, and the other is distributed caching, which is the safest way to cache.
  See programs directly:

public static void Main (string[] args) { 
 
  Configuration cfg = new Configuration (). Configure (); 
  Sessionfactory sessionfactory = Cfg.buildsessionfactory (); 
  Session session = Sessionfactory.opensession (); 
     
  User user = (user) session.load (user.class,new Long); 
  System.out.println (User.getname ()); 
     
  User User2 = (user) session.load (user.class,new Long); 
  System.out.println (User2.getname ()); 
     
  Session.close (); 
} 

Look at the results:

Hibernate:select user0_. user_id as user1_0_0_, user0_. User_name as user2_0_0_, user0_.age as age0_0_ from USER user0_ where user0_. User_id=? 
shun123123 
shun123123 

In the example we used two load, but there was only one SQL statement in the result, which indicated that it was queried only once.
Why, then? This means that the hibernate cache works. After the first query is completed, the hibernate after the check out of the entity in the cache, the next time check the first cache, see if there is a corresponding ID entity exists, if there is a direct removal, otherwise the database query.

Here we modify the code to:

User user = (user) session.load (user.class,new Long); 
System.out.println (User.getname ()); 
     
Session.evict user 
     
user2 = (user) session.load (user.class,new Long) by deleting user from the cache; 
System.out.println (User2.getname ()); 
     
Session.close (); 

See results:

Hibernate:select user0_. user_id as user1_0_0_, user0_. User_name as user2_0_0_, user0_.age as age0_0_ from USER user0_ where user0_. User_id=? 
shun123123 
hibernate:select user0_. user_id as user1_0_0_, user0_. User_name as user2_0_0_, user0_.age as age0_0_ from USER user0_ where user0_. User_id=? 
Shun123123 

When we remove user from the cache, the second query is also retrieved directly from the database.

Second-level caching small Talk
first look at the entity class:

public class User implements serializable{public 
 
  Long ID; 
  private String name; 
  private int age; 
   
} 

The mapping file is omitted and should be written by everyone.
Let's look at the hibernate configuration file:

<property name= "Hibernate.cache.provider_class" >org.hibernate.cache.EhCacheProvider</property> 
<property name= "Hibernate.cache.use_second_level_cache" >true</property> 
<property name= " Hibernate.cache.use_query_cache ">true</property> 

We see that we have specified ehcache this provision class in Provider_class, so we also need ehcache.xml to be placed in Classpath:

<?xml version= "1.0" encoding= "UTF-8"?> 
<ehcache> 
  <diskstore path= "Java.io.path"/> 
  <defaultcache  
    maxelementsinmemory= "10000" 
    eternal= "false" 
    timetoidleseconds= " 
    timetoliveseconds= "overflowtodisk=" " 
    true" 
    /> 
</ehcache> 

Next, let's look at the test method directly:

public static void Main (string[] args) { 
 
  Configuration cfg = new Configuration (). Configure (); 
  Sessionfactory sessionfactory = Cfg.buildsessionfactory (); 
  Session session = Sessionfactory.opensession (); 
 
  Query query = Session.createquery ("From user user where name = ' shun123 '"); 
  Iterator iter = Query.iterate (); 
  while (Iter.hasnext ()) { 
    System.out.println ((User) Iter.next ()). GetName ()); 
  } 
   
  Session.close (); 
   
  Session Session2 = Sessionfactory.opensession (); 
  Query Query2 = Session2.createquery ("From user user where name= ' shun123 '"); 
  Iterator iter2 = Query2.iterate (); 
  while (Iter2.hasnext ()) { 
    System.out.println ((User) Iter2.next ()). GetName ()); 
  } 
   
  Session2.close (); 
 
} 

After running, you can see:

Hibernate:select user0_. user_id as col_0_0_ from USER user0_ where user0_. User_name= ' shun123 ' 
hibernate:select user0_. user_id as user1_0_0_, user0_. User_name as user2_0_0_, user0_.age as age0_0_ from USER user0_ where user0_. User_id=? 
shun123 
hibernate:select user0_. user_id as col_0_0_ from USER user0_ where user0_. User_name= ' shun123 ' 
shun123 

We can see that it only performs a single search, while the second query does not take out IDs for searching, thanks largely to level two caching.

Let's first analyze the code in the test method. In the test method, we opened two sessions and created two queries to do the same query respectively. But two sessions can share the cache, which is the level two cache, the sessionfactory cache. As long as our session is created by the same sessionfactory, we can reduce the interaction with the database by sharing a level two cache.
Let's take a look at the meaning in the configuration file:

<property name= "Hibernate.cache.provider_class" >org.hibernate.cache.EhCacheProvider</property> 
<property name= "Hibernate.cache.use_second_level_cache" >true</property> 
<property name= " Hibernate.cache.use_query_cache ">true</property> 

If we need to use level two caching, we first need to configure:

<property name= "Hibernate.cache.use_second_level_cache" >true</property> 

To account for the two level of the cache, and then through:

<property name= "Hibernate.cache.provider_class" >org.hibernate.cache.EhCacheProvider</property> 

Specifies the level two cache provision class, in general we all use Ehcache, other my temporarily useless to, also not very clear, therefore temporarily does not speak.
As we have just shown, we only need to configure the top two, fully functional, using level two caching.
So what's the third sentence for?

<property name= "Hibernate.cache.use_query_cache" >true</property> 

This configuration indicates that we need to use caching when querying, if we need to use this method to call Query.setcacheable (true) in advance to enable.

Let's look at the code together (we don't enable caching first):

public static void Main (string[] args) { 
 
  Configuration cfg = new Configuration (). Configure (); 
  Sessionfactory sessionfactory = Cfg.buildsessionfactory (); 
  Session session = Sessionfactory.opensession (); 
 
  Query query = Session.createquery ("From user user where name = ' shun123 '"); 
  List List = Query.list (); 
  for (int i = 0; i < list.size (); i++) { 
    System.out.println ((User) list.get (i)). GetName ()); 
   
  Session.close (); 
   
  Session Session2 = Sessionfactory.opensession (); 
  Query Query2 = Session2.createquery ("From user user where name= ' shun123 '"); 
  List List2 = Query2.list (); 
  for (int i = 0; i < list2.size (); i++) { 
    System.out.println ((User) list.get (i)). GetName ()); 
   
  Session2.close (); 
 
} 

The result of this output is:

Hibernate:select user0_. user_id as user1_0_, user0_. User_name as user2_0_, user0_.age as age0_ from USER user0_ where user0_. User_name= ' shun123 ' 
shun123 
hibernate:select user0_. user_id as user1_0_, user0_. User_name as user2_0_, user0_.age as age0_ from USER user0_ where user0_. User_name= ' shun123 ' 
shun123 

We see that it doesn't take advantage of caching because we use the list here, and the list is read-only for caching. So there's going to be two queries.
So let's revise this:

public static void Main (string[] args) {Configuration cfg = new Configuration (). Configure (); 
  Sessionfactory sessionfactory = Cfg.buildsessionfactory (); 
 
  Session session = Sessionfactory.opensession (); 
  Query query = Session.createquery ("From user user where name = ' shun123 '"); <span style= "Background-color: #ffffff;" ><span style= "color: #ff0000;" 
  >query.setcacheable (true);</span></span> list = Query.list (); 
  for (int i = 0; i < list.size (); i++) {System.out.println (((User) list.get (i)). GetName ()); 
   
  } session.close (); 
  Session Session2 = Sessionfactory.opensession (); 
  Query Query2 = Session2.createquery ("From user user where name= ' shun123 '"); <span style= "color: #ff0000;" 
  >query2.setcacheable (True);</span> List list2 = Query2.list (); 
  for (int i = 0; i < list2.size (); i++) {System.out.println (((User) list.get (i)). GetName ()); 
 
} session2.close (); 
 }

See the red two-sentence code, this is the two we added to open the query cache code, now we see the results:

Hibernate:select user0_. user_id as user1_0_, user0_. User_name as user2_0_, user0_.age as age0_ from USER user0_ where user0_. User_name= ' shun123 ' 
shun123 
shun123 

There's only one query left, why? In those two lines of red code, we turned on the cache, and remember, you need to use it two times. You can use query caching by setting two query to cacheable.
The criteria is similar, for the avoidance of some children's shoes forget the criteria for how to write, I still put the code:

public static void Main (string[] args) { 
 
  Configuration cfg = new Configuration (). Configure (); 
  Sessionfactory sessionfactory = Cfg.buildsessionfactory (); 
  Session session = Sessionfactory.opensession (); 
 
  Criteria criteria1 = Session.createcriteria (user.class); 
  Criteria1.setcacheable (true); 
  Criteria1.add (Restrictions.eq ("name", "shun123")); 
  List List = Criteria1.list (); 
  for (int i = 0; i < list.size (); i++) { 
    System.out.println ((User) list.get (i)). GetName ()); 
   
  Session.close (); 
   
  Session Session2 = Sessionfactory.opensession (); 
  Criteria criteria2 = Session2.createcriteria (user.class); 
  Criteria2.setcacheable (true); 
  Criteria2.add (Restrictions.eq ("name", "shun123")); 
  List List2 = Criteria2.list (); 
  for (int i = 0; i < list2.size (); i++) { 
    System.out.println ((User) list.get (i)). GetName ()); 
   
  Session2.close (); 
 
} 

We see the results:

Hibernate:select This_. user_id as user1_0_0_, This_. User_name as user2_0_0_, this_.age as age0_0_ from USER This_ where This_. User_name=? 
Shun123 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.