Maison  >  Article  >  Java  >  Explication détaillée du cache de deuxième niveau en Java

Explication détaillée du cache de deuxième niveau en Java

Y2J
Y2Joriginal
2017-05-16 09:59:083620parcourir

Cet article présente principalement l'explication détaillée du cache de deuxième niveau d'hibernation en Java. L'éditeur pense que c'est assez bon. Maintenant, je vais le partager avec vous et le donner comme référence. Suivons l'éditeur pour jeter un œil

Cache de deuxième niveau d'Hibernate

1 Aperçu du cache

Cache ) : Un concept très courant dans le domaine informatique. Il est situé entre l'application et la source de stockage de données permanente (telle qu'un fichier ou une base de données sur le disque dur). Sa fonction est de réduire la fréquence de lecture et d'écriture directe de l'application sur la source de stockage de données permanente, améliorant ainsi le fonctionnement de l'application. performance. Les données du cache sont une copie des données de la source de stockage de données. Le support physique du cache est généralement la mémoire

hibernate fournit deux niveaux de cache

Le premier niveau de cache est Session cache de niveau, qui est un cache à l'échelle de la transaction. Ce niveau de cache est géré par hibernate et ne nécessite généralement aucune intervention

Le deuxième niveau de cache est le cache de niveau SessionFactory, qui est un cache à l'échelle du processus

Le cache d'Hibernate peut être divisé en deux catégories :

Cache intégré : Hibernate est fourni avec et ne peut pas être désinstallé. Habituellement, pendant la phase d'initialisation d'Hibernate, Hibernate stockera le mappage. les métadonnées et les instructions SQL prédéfinies sont placées dans le cache SessionFactory. Les métadonnées de mappage sont une copie des données du fichier de mappage, et les instructions SQL prédéfinies sont extraites par Hibernate en fonction des métadonnées de mappage. Le cache intégré est lu. uniquement.

Cache externe (cache de deuxième niveau) : Un plug-in de cache configurable Par défaut, SessionFactory n'activera pas ce plug-in de cache. Les données du cache externe sont une copie du. données de base de données, externes Le support physique du cache peut être la mémoire ou le disque dur

2. Comprendre la stratégie d'accès simultané du cache de deuxième niveau

3. Configurer le cache de deuxième niveau à l'échelle du processus (configuration du cache ehcache)

1 Copier ehcache-1.5.0 .jar dans le répertoire lib du projet en cours

Dépend de backport-util-concurrent et commons-logging

2 Activez le cache de deuxième niveau

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

3 pour spécifier le fournisseur de cache

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

4 Spécifiez la classe qui utilise le cache de deuxième niveau

La première méthode consiste à utiliser la configuration *.hbm.xml de la classe

Sélectionnez la classe de persistance qui doit utiliser le cache de deuxième niveau et définissez la politique d'accès simultané de son cache de deuxième niveau. de l'élément 06fc722e8309f4fc3af5f9b05c0cd286 indique qu'Hibernate mettra en cache l'attribut simple de l'objet, mais les attributs définis ne seront pas mis en cache si vous souhaitez mettre en cache les éléments du fichier 06fc722e8309f4fc3af5f9b05c0cd286 set attributs, vous devez ajouter le sous-élément 62aecd17e676a41d3547c3bf97bb07b0 à l'élément 5a9c31804c75b3b74adac946f50af902. Méthode 2. Configurez dans le fichier hibernate.cfg.xml (recommandé).

  <!-- 指定使用二级缓存的类 放在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"/>

5 Configurer le fichier de configuration par défaut d'ehcache ehcache.xml (nom fixe) (mettez-le sur le chemin de classe)

<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 = &#39;奶茶&#39; 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(); 
 } 
}

【Recommandations associées】

1 Recommandation spéciale : "php Programmer Toolbox" V0. 1 version téléchargée

2. Tutoriel vidéo gratuit Java

3 Manuel du didacticiel JAVA

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn