Home>

hibernate's second-level cache

First, the cache overview

Cache:A very common concept in the computer field.It is between the application and the persistent data storage source (such as a file or database on the hard disk).So as to improve the running performance of the application.The data in the cache is a copy of the data in the data storage source.Cached physical media is usually memory

Hibernate provides two levels of caching

The first level of cache is the session level cache,It is a transaction-wide cache.This level of cache is managed by hibernate and generally requires no intervention

The second level of cache is the sessionfactory level of cache,It is a process-wide cache

Hibernate's cache can be divided into two categories:

Built-in cache:Hibernate comes with it, can not be unloaded. Usually during the initialization phase of hibernate, hibernate will put the mapping metadata and predefined sql statements into the cache of sessionfactory, The mapping metadata is a copy of the data in the mapping file, When pre-defined SQL statements, hibernate pushes them out according to the mapping metadata. This built-in cache is read-only.

External cache (second-level cache):a configurable cache plugin. By default, sessionfactory does not enable this caching plugin. The data in the external cache is a copy of the database data, External cached physical media can be memory or hard disk

Second, understand the concurrent access strategy of the second-level cache

Third, configure the process-level secondary cache (configure ehcache cache)

1 Copy ehcache-1.5.0.jar to the lib directory of the current project

Depends on backport-util-concurrent and commons-logging

2 Turn on the secondary cache

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

3 To specify the vendor of the cache

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

4 Specify the class to use the second-level cache

Method 1:Use the * .hbm.xml configuration of the class

Select the persistent class that needs to use the second-level cache, Set its concurrent access policy for the secondary cache, The cache child element of theelement indicates that hibernate will cache simple attributes of the object, But does not cache collection properties, If i want to cache elements in a collection property, You must add achild element to theelement

Method two configuration in hibernate.cfg.xml file (recommended)

 <!-Specify the class to use the second-level cache under maping->
  <!-Configure class-level L2 cache->
  <class-cache usage="read-write" />
  <class-cache usage="read-write" />
  <!-Configure collection-level secondary cache->
  <collection-cache collection="com.sihai.c3p0.customer.orders"
         usage="read-write" />

5 Configure the ehcache default configuration file ehcache.xml (fixed name) (placed in the classpath)

<ehcache xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:nonamespaceschemalocation="../config/ehcache.xsd">
 <diskstore path="c:/ehcache" />
 <defaultcache
   maxelementsinmemory="5"
   eternal="false"
   timetoidleseconds="120"
   timetoliveseconds="120"
   overflowtodisk="true"
   maxelementsondisk="10000000"
   diskpersistent="false"
   diskexpirythreadintervalseconds="120"
   memorystoreevictionpolicy="lru"
   />
</ehcache>

Fourth, test

package com.sihai.hibernate3.test;
import java.util.iterator;
import java.util.list;
import org.hibernate.query;
import org.hibernate.session;
import org.hibernate.transaction;
import org.junit.test;
import com.sihai.hibernate3.demo1.customer;
import com.sihai.hibernate3.demo1.order;
import com.sihai.utils.hibernateutils;
public class hibernatetest6 {
 @test
 //Query cache test
 public void demo9 () {
  session session=hibernateutils.getcurrentsession ();
  transaction tx=session.begintransaction ();
  query query=session.createquery ("select c.cname from customer c");
  //Use query cache:
  query.setcacheable (true);
  query.list ();
  tx.commit ();
  session=hibernateutils.getcurrentsession ();
  tx=session.begintransaction ();
  query=session.createquery ("select c.cname from customer c");
  query.setcacheable (true);
  query.list ();
  tx.commit ();
 }
 @suppresswarnings ("unused")
 @test
 //update timestamp
 public void demo8 () {
  session session=hibernateutils.getcurrentsession ();
  transaction tx=session.begintransaction ();
  customer customer=(customer) session.get (customer.class, 2);
  session.createquery ("update customer set cname =" Milk Tea "where cid=2"). executeupdate ();
  tx.commit ();
  session=hibernateutils.getcurrentsession ();
  tx=session.begintransaction ();
  customer customer2=(customer) session.get (customer.class, 2);
  tx.commit ();
 }
 @suppresswarnings ("all")
 @test
 //write data in memory to hard disk
 public void demo7 () {
  session session=hibernateutils.getcurrentsession ();
  transaction tx=session.begintransaction ();
  list<order>list=session.createquery ("from order"). list ();
  tx.commit ();
 }
 @test
 //Updates from the primary cache will be synchronized to the secondary cache:
 public void demo6 () {
  session session=hibernateutils.getcurrentsession ();
  transaction tx=session.begintransaction ();
  customer customer=(customer) session.get (customer.class, 1);
  customer.setcname ("hibiscus");
  tx.commit ();
  session=hibernateutils.getcurrentsession ();
  tx=session.begintransaction ();
  customer customer2=(customer) session.get (customer.class, 1);
  tx.commit ();
 }
 @suppresswarnings ("unchecked")
 @test
 //iterate () method can query all information.
 //iterate method will send n + 1 sql queries. But it will use the second level cached data
 public void demo5 () {
  session session=hibernateutils.getcurrentsession ();
  transaction tx=session.begintransaction ();
  //n + 1 pieces of sql to query.
  iterator<customer>iterator=session.createquery ("from customer"). iterate ();
  while (iterator.hasnext ()) {
   customer customer=iterator.next ();
   system.out.println (customer);
  }
  tx.commit ();
  session=hibernateutils.getcurrentsession ();
  tx=session.begintransaction ();
  iterator=session.createquery ("from customer"). iterate ();
  while (iterator.hasnext ()) {
   customer customer=iterator.next ();
   system.out.println (customer);
  }
  tx.commit ();
 }
 @suppresswarnings ("unchecked")
 @test
 //Query all.
The list () method of the query interface.
 //list () method will put data into the secondary cache,However, the data in the secondary cache is not used.
 public void demo4 () {
  session session=hibernateutils.getcurrentsession ();
  transaction tx=session.begintransaction ();
  //Query all customers:
  //The list method will put data into the secondary cache.
  list<customer>list=session.createquery ("from customer"). list ();
  for (customer customer:list) {
   system.out.println (customer.getcname ());
  }
  tx.commit ();
  session=hibernateutils.getcurrentsession ();
  tx=session.begintransaction ();
  //customer customer=(customer) session.get (customer.class, 1);//No sql occurred, data obtained from the secondary cache.
  //The list () method does not use the second-level cached data.
  list=session.createquery ("from customer"). list ();
  for (customer customer:list) {
   system.out.println (customer.getcname ());
  }
  tx.commit ();
 }
 @test
 //L2 cache collection buffer features:
 public void demo3 () {
  session session=hibernateutils.getcurrentsession ();
  transaction tx=session.begintransaction ();
  customer customer=(customer) session.get (customer.class, 1);
  //Query the customer's order.
  system.out.println ("Number of orders:" + customer.getorders (). size ());
  tx.commit ();
  session=hibernateutils.getcurrentsession ();
  tx=session.begintransaction ();
  customer customer2=(customer) session.get (customer.class, 1);
  //Query the customer's order.
  system.out.println ("Number of orders:" + customer2.getorders (). size ());
  tx.commit ();
 }
 @suppresswarnings ("unused")
 @test
 //Configure the secondary cache
 public void demo2 () {
  session session=hibernateutils.getcurrentsession ();
  transaction tx=session.begintransaction ();
  customer customer1=(customer) session.get (customer.class, 1);//Send sql.
  customer customer2=(customer) session.get (customer.class, 1);//Does not send sql.
  system.out.println (customer1 == customer2);
  tx.commit ();
  session=hibernateutils.getcurrentsession ();
  tx=session.begintransaction ();
  customer customer3=(customer) session.get (customer.class, 1);//Does not send sql.
  customer customer4=(customer) session.get (customer.class, 1);//Does not send sql.
  system.out.println (customer3 == customer4);
  tx.commit ();
 }
 @suppresswarnings ("unused")
 @test
 //No secondary cache is configured
 public void demo1 () {
  session session=hibernateutils.getcurrentsession ();
  transaction tx=session.begintransaction ();
  customer customer1=(customer) session.get (customer.class, 1);//Send sql.
  customer customer2=(customer) session.get (customer.class, 1);//Does not send sql.
  tx.commit ();
  session=hibernateutils.getcurrentsession ();
  tx=session.begintransaction ();
  customer customer3=(customer) session.get (customer.class, 1);//Send sql.
  tx.commit ();
 }
}
  • Previous Design pattern of homemade PHP framework
  • Next Summary of Inheritance in JavaScript