Hibernate's Level two cache----the level two cache of collection and query

Source: Internet
Author: User

Collection Level Two cache:

When you do not use a two-level cache for a collection:
Run the following code:

@Test Public voidtestCollectionSecondLevelCache1 () {Department Dept= (Department) session.get (Department.class, 3); System.out.println (Dept.getid ()+"   "+dept.getname ());                 System.out.println (Dept.getemps (). Size ());        Transaction.commit ();                Session.close (); Session=sessionfactory.opensession (); Transaction=session.begintransaction (); Department Dept2= (Department) session.get (Department.class, 3); Set<Employee> emps=Dept2.getemps ();  for(Employee employee:emps) {System.out.println (Employee.getid ()+"      " +employee.getname ()); }    }

The resulting results are as follows:

Hibernate:
Select
Department0_.id as id1_0_0_,
Department0_.name as Name2_0_0_
From
Gg_department department0_
where
Department0_.id=?
3 B
Hibernate:
Select
emps0_. dept_id as Dept_id5_0_1_,
Emps0_.id as Id1_1_1_,
Emps0_.id as id1_1_0_,
Emps0_.name as name2_1_0_,
emps0_. SALARY as salary3_1_0_,
emps0_. EMAIL as email4_1_0_,
emps0_. dept_id as Dept_id5_1_0_
From
Gg_employee emps0_
where
emps0_. Dept_id=?
3
--------------------------------------------------
Hibernate:
Select
Department0_.id as id1_0_0_,
Department0_.name as Name2_0_0_
From
Gg_department department0_
where
Department0_.id=?
Hibernate:
Select
emps0_. dept_id as Dept_id5_0_1_,
Emps0_.id as Id1_1_1_,
Emps0_.id as id1_1_0_,
Emps0_.name as name2_1_0_,
emps0_. SALARY as salary3_1_0_,
emps0_. EMAIL as email4_1_0_,
emps0_. dept_id as Dept_id5_1_0_
From
Gg_employee emps0_
where
emps0_. Dept_id=?
5 EE
7 GG
6 FF

1 if the session is not closed, it should be sent two SELECT statements, because the session cache has initialized the department and employee objects, but the session closed, the session of the first-level cache is not it, So the department and employee objects at this time are free objects and must be sent a SELECT statement to the data when they need to be obtained again

But what if we enabled the collection of level two caches??

Steps to set up a level two cache:

I. Configuring the use of level two caching for collections

<collection-cache usage= "Read-write" collection= "Com.atguigu.hibernate.entities.Department.emps"/>

Can also be configured in the. hbm.xml file

<set name= "Emps" table= "Gg_employee" inverse= "true" lazy= "true" >
<cache usage= "Read-write"/>
<key>
<column name= "dept_id"/>
</key>
<one-to-many class= "Com.atguigu.hibernate.entities.Employee"/>
</set>

II. Note: You also need to configure the elements in the collection to correspond to the persistence class also use level two cache! Otherwise, there will be more than n SQL statements. (Collection cache relies on level two caching for persisted classes)

For example, configure the two-level cache for a collection in the Hibernate.cfg.xml file:

<class-cache usage= "Read-write" class= "Com.atguigu.hibernate.entities.Employee"/>
<class-cache usage= "Read-write" class= "Com.atguigu.hibernate.entities.Department"/>
<collection-cache usage= "Read-write" collection= "Com.atguigu.hibernate.entities.Department.emps"/>

code example:

Using a collection of level two caches results in this:

Hibernate:     Select        department0_.id as id1_0_0_,        Department0_.name as name2_0_0_     from        gg_ DEPARTMENT department0_     where        department0_.id=?3   bhibernate:     select        emps0_. dept_id as dept_id5_0_1_,        emps0_.id as id1_1_1_, emps0_.id as id1_1_0_, emps0_.name as        name2_1_0_,        emps0_. SALARY as salary3_1_0_,        emps0_. EMAIL as email4_1_0_,        emps0_. dept_id as dept_id5_1_0_     from        gg_employee emps0_     where        emps0_. Dept_id=?3--------------------------------------------------6      FF5      EE7      GG

Query cache:

Query caching is a use of level two caching
Query cache:
For frequently used query statements, if query caching is enabled, hibernate will store the query results in a level two cache when the query is executed for the first time. When you execute the query statement again later, you can improve query performance by simply getting the query results from the cache.
The query cache applies to the following scenarios: 1 query statements that are used frequently when the application is running. 2 The database data associated with the query statement is rarely inserted, deleted, or updated.

In the use of hibernate, most of the time people are talking about first-level cache and level two cache, often ignoring the query cache. In fact, Hibernate's query cache plays an equally important role in the use process. Hibernate's query cache is primarily a cache of common attribute result sets, whereas the result set for an entity object caches only the ID. In the case of a first-level cache, where the two-level cache and the query cache are open, the query operation is as follows:
Query the Normal property---"will go to the query cache first, if not, then query the database;
Querying entity---takes an ID in the query cache first, and if so, the entity is taken from the ID to the cache (level/level two), and the database is queried if the entity is not in the cache.

Implementation steps:
1 The query cache is a subcategory of level two cache, so the query cache is dependent on the level two cache, so you must configure a two-level cache before using the query cache, and a two-level cache there's no mention of that.
2declaring open query cache in Hibernate configuration file

<property name= "Cache.use_query_cache" >true</property>
3 Call the Setcacheable (true) method of query or Criteria to enable query caching for the current (that is, the Execute setcacheable (true) method after the query statement you need)

Example Description:
Test code:

@Test      Public void Testquerycache () {        = Session.createquery ("from Employee");         List<Employee> emps = query.list ();        System.out.println (Emps.size ());        System.out.println (Emps.iterator (). Next (). GetClass ());                 = query.list ();        System.out.println (Emps.size ());        }

Operation Result:

Hibernate:     select        employee0_.id as id1_1_,        employee0_.name as name2_1_,        employee0_. SALARY as salary3_1_,        employee0_. EMAIL as email4_1_,        employee0_. dept_id as dept_id5_1_     from        gg_employee employee0_class  Com.atguigu.hibernate.entities.EmployeeHibernate:     Select        employee0_.id as id1_1_,        employee0_.name As name2_1_,        employee0_. SALARY as salary3_1_,        employee0_. EMAIL as email4_1_,        employee0_. dept_id as dept_id5_1_     from        gg_employee employee0_25

Here twice I have executed the same HQL statement to query, but Hibernate has sent me two SELECT statements, is there a piece is superfluous? This means that, by default, the cache set is not valid for HQL and QBC queries, but can be made effective by setting the query cache (Note that QBC queries also need to be set)
When the query cache is started, the result is:

Hibernate:     select        employee0_.id as id1_1_,        employee0_.name as name2_1_,        employee0_. SALARY as salary3_1_,        employee0_. EMAIL as email4_1_,        employee0_. dept_id as dept_id5_1_     from        gg_employee employee0_class  Com.atguigu.hibernate.entities.Employee25

Send only a SELECT statement, that is not greatly reduce the burden of my program

There's one more thing to be aware of. The query cache differs from the first level/level two cache, and the lifetime of the query cache is indeterminate, and the life cycle of the query cache ends when the currently associated table changes. For example, run the following test code:
@Test Public voidTestquerycache () {query Query= Session.createquery ("from Employee e where e.id=1"); Query.setcacheable (true); List<Employee> Emps =query.list ();        System.out.println (Emps.size ());                System.out.println (Emps.iterator (). Next (). GetClass ()); Employee Employee=NewEmployee (); Employee.setemail ("[Email protected]"); Employee.setname ("Jeremy");        Employee.setsalary (8000F);                Session.save (employee); Emps=query.list ();                System.out.println (Emps.size ()); //Criteria = Session.createcriteria (Employee.class); //criteria.setcacheable (true);}

Operation Result:

 hibernate:select employee0_.id as id1_1_, employee0_.name as Name2_1 _, employee0_. SALARY as Salary3_1_, employee0_. EMAIL as Email4_1_, employee0_.  dept_id as dept_id5_1_ from Gg_employee employee0_ where employee0_.id  =101class   Com.atguigu.hibernate.entities.EmployeeHibernate:insert into G G_employee (NAME, SALARY, EMAIL, dept_id) VALUES (?,?,?,?         =101 


I made the first HQL query and then added the data table, the data table has changed, the query cache is closed (even if the update operation on my HQL statement query results have no effect, but the query cache is closed)

If the query cache is not closed, it is already sending a SELECT statement and an INSERT statement, but now it is sending two SELECT statements, an INSERT statement, so it is proven that the query cache is automatically closed when the query cache-related table is updated, which is important to remember

Hibernate's Level two cache----the level two cache of collection and query

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.