Home >Java >javaTutorial >Detailed explanation of second-level cache in java
This article mainly introduces the detailed explanation of hibernate second-level cache in Java. The editor thinks it is quite good. Now I will share it with you and give it as a reference. Let’s follow the editor to take a look
Hibernate’s second-level cache
1. Cache overview
Cache ): A very common concept in the computer field. It is located between the application and the permanent data storage source (such as a file or database on the hard disk). Its function is to reduce the frequency of the application directly reading and writing the permanent data storage source, thereby improving the application's running performance. The data in the cache is a copy of the data in the data storage source. The physical medium of cache is usually memory
hibernate provides two levels of cache
The first level of cache isSession Level cache, which is a transaction-wide cache. This level of cache is managed by hibernate, and generally no intervention is required
The second level of cache is the SessionFactory level cache, which is a process-wide cache
Hibernate's cache can be divided into two categories:
Built-in cache: Hibernate comes with it and cannot be uninstalled. Usually during the initialization phase of Hibernate, Hibernate will store the mapping metadata and predefined SQL statements are placed in the SessionFactory cache. The mapping metadata is a copy of the data in the mapping file, and the predefined SQL statements are pushed out by Hibernate based on the mapping metadata. The built-in cache is read-only.
External cache (second-level cache): A configurable cache plug-in. By default, SessionFactory will not enable this cache plug-in. The data in the external cache is a copy of the database data, external The physical medium of the cache can be memory or hard disk
2. Understand the concurrent access strategy of the second-level cache
3. Configure the process-wide second-level cache (configuring ehcache cache)
1 Copy ehcache-1.5.0.jar to the lib directory of the current project
Depend on backport-util-concurrent and commons-logging
2 Turn on the second level cache
<property name="hibernate.cache.use_second_level_cache">true</property>
3 To specify the cache Supplier
<property name="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider</property>
4 Specify the class that uses the second-level cache
Method 1 Use the *.hbm.xml configuration of the class
Select what you need to use The persistence class of the second-level cache sets the concurrent access policy of its second-level cache. The cache sub-element of the 06fc722e8309f4fc3af5f9b05c0cd286 element indicates that Hibernate will cache the simple attributes of the object, but Collection attributes will not be cached. If you want to cache the elements in the collection attributes, you must add the 62aecd17e676a41d3547c3bf97bb07b0 sub-element to the ee662543c52e99a3f804b997f1e04750 element. Method 2 in hibernate.cfg. Configuration in xml file (recommendation) <!-- 指定使用二级缓存的类 放在maping下面 -->
<!-- 配置类级别的二级缓存 -->
<class-cache class="com.sihai.c3p0.Customer" usage="read-write"/>
<class-cache class="com.sihai.c3p0.Order" usage="read-write"/>
<!-- 配置集合级别的二级缓存 -->
<collection-cache collection="com.sihai.c3p0.Customer.orders"
usage="read-write"/>
Configuration file ehcache.xml (fixed name) (placed in the class path)
<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>
4. 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 // 查询缓存的测试 public void demo9(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Query query = session.createQuery("select c.cname from Customer c"); // 使用查询缓存: 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 // 更新时间戳 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 = '奶茶' 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 // 将内存中的数据写到硬盘 public void demo7(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); List<Order> list = session.createQuery("from Order").list(); tx.commit(); } @Test // 一级缓存的更新会同步到二级缓存: public void demo6(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Customer customer = (Customer) session.get(Customer.class, 1); customer.setCname("芙蓉"); tx.commit(); session = HibernateUtils.getCurrentSession(); tx = session.beginTransaction(); Customer customer2 = (Customer) session.get(Customer.class, 1); tx.commit(); } @SuppressWarnings("unchecked") @Test // iterate()方法可以查询所有信息. // iterate方法会发送N+1条SQL查询.但是会使用二级缓存的数据 public void demo5(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); // N+1条SQL去查询. 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接口的list()方法. // list()方法会向二级缓存中放数据,但是不会使用二级缓存中的数据. public void demo4(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); // 查询所有客户: // list方法会向二级缓存中放入数据的. 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);// 没有发生SQL ,从二级缓存获取的数据. // list()方法没有使用二级缓存的数据. list = session.createQuery("from Customer").list(); for (Customer customer : list) { System.out.println(customer.getCname()); } tx.commit(); } @Test // 二级缓存的集合缓冲区特点: public void demo3(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Customer customer = (Customer) session.get(Customer.class, 1); // 查询客户的订单. System.out.println("订单的数量:"+customer.getOrders().size()); tx.commit(); session = HibernateUtils.getCurrentSession(); tx = session.beginTransaction(); Customer customer2 = (Customer) session.get(Customer.class, 1); // 查询客户的订单. System.out.println("订单的数量:"+customer2.getOrders().size()); tx.commit(); } @SuppressWarnings("unused") @Test // 配置二级缓存的情况 public void demo2(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Customer customer1 = (Customer) session.get(Customer.class, 1);// 发送SQL. Customer customer2 = (Customer) session.get(Customer.class, 1);// 不发送SQL. System.out.println(customer1 == customer2); tx.commit(); session = HibernateUtils.getCurrentSession(); tx = session.beginTransaction(); Customer customer3 = (Customer) session.get(Customer.class, 1);// 不发送SQL. Customer customer4 = (Customer) session.get(Customer.class, 1);// 不发送SQL. System.out.println(customer3 == customer4); tx.commit(); } @SuppressWarnings("unused") @Test // 没有配置二级缓存的情况 public void demo1(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Customer customer1 = (Customer) session.get(Customer.class, 1);// 发送SQL. Customer customer2 = (Customer) session.get(Customer.class, 1);// 不发送SQL. tx.commit(); session = HibernateUtils.getCurrentSession(); tx = session.beginTransaction(); Customer customer3 = (Customer) session.get(Customer.class, 1);// 发送SQL. tx.commit(); } }[Related recommendations]1.
Special recommendation:"php programmer toolbox ”V0.1 version download
2. 3.The above is the detailed content of Detailed explanation of second-level cache in java. For more information, please follow other related articles on the PHP Chinese website!