Maison  >  Article  >  Java  >  Explication détaillée des exemples de cache dans mybatis

Explication détaillée des exemples de cache dans mybatis

Y2J
Y2Joriginal
2017-05-13 10:40:541545parcourir

Cet article présente principalement le cache de requêtes du didacticiel mybatis (cache de premier niveau, cache de deuxième niveau et ehcache intégré), qui a une certaine valeur de référence. Les amis intéressés peuvent s'y référer

1. La signification de la mise en cache

Mettez les données fréquemment interrogées par les utilisateurs dans le cache (mémoire). Les utilisateurs n'ont pas besoin d'interroger les données du disque (fichier de données de base de données relationnelle), mais de. la requête de cache, améliorant ainsi l'efficacité des requêtes et résolvant le problème de performances des systèmes à haute concurrence.

2 cache de couche de persistance mybatis

mybatis fournit un cache de premier niveau et un cache de deuxième niveau

Le cache de premier niveau mybatis est un niveau SqlSession. sqlsession ne peut accéder qu'aux données de son propre cache de premier niveau. Le cache de deuxième niveau se trouve à travers sqlSession et. est un cache au niveau du mappeur. Pour Le cache au niveau du mappeur peut être partagé par différentes sessions SQL.

Cache 3 niveau 1

Principe 3.1

La première fois qu'une requête SQL est émise, le résultat de la requête SQL est écrit dans le cache de premier niveau de sqlsession. La structure de données utilisée dans le cache est une mape6fd748e50e82e7bde0d1e0efd3285df

<.>clé : hashcode+ sql+paramètre d'entrée sql + paramètre de sortie (l'identifiant unique de sql)


valeur : informations utilisateur


Si la même session sql émet le même sql encore une fois, il sera récupéré du cache. N'utilisez pas la base de données. S'il y a une opération de validation (modifier, ajouter,

supprimer) entre deux fois, la zone de cache de premier niveau dans cette session sql sera effacée, et la prochaine fois que vous accéderez au cache pour l'interroger, vous ne pourra pas l'interroger, vous devez donc l'interroger à partir de la base de données, l'interroger à nouveau depuis la base de données vers le cache.

Chaque requête interroge d'abord le cache :


Si la requête est trouvée dans le cache, les

données du cacheRetournez directement.

Si la requête est introuvable dans le cache, interrogez-la depuis la base de données :


3.2 Cache niveau 1 configuration

Mybatis prend en charge le cache de premier niveau par défaut et ne nécessite aucune configuration.


Remarque : le développement de l'agent mappeur est effectué après l'intégration de mybatis et spring. Le cache de premier niveau n'est pas pris en charge. Mybatis et spring génèrent des objets mapper

. et les modèles selon le modèle du mappeur. Fermez la session sql uniformément à la fin.

3.3 Test de cache niveau 1


//一级缓存 
  @Test 
  public void testCache1() throws Exception { 
 
    SqlSession sqlSession = sqlSessionFactory.openSession(); 
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class); 
     
    //第一次查询用户id为1的用户 
    User user = userMapper.findUserById(1); 
    System.out.println(user); 
     
    //中间修改用户要清空缓存,目的防止查询出脏数据 
    /*user.setUsername("测试用户2"); 
    userMapper.updateUser(user); 
    sqlSession.commit();*/ 
     
    //第二次查询用户id为1的用户 
    User user2 = userMapper.findUserById(1); 
    System.out.println(user2); 
     
    sqlSession.close(); 
     
 
  }

4 Cache niveau 2

4.1 Principe

La portée du cache de deuxième niveau est le niveau du mappeur (le mappeur est le même

namespace), le mappeur crée une structure de données de cache en unités d'espace de noms, et la structure est mapf1e34d8162e3ac965af665baa7938918.

Chaque fois que vous effectuez une requête, vérifiez d'abord si le cache de deuxième niveau est activé. S'il est activé pour récupérer les données mises en cache à partir de la structure de données du cache de deuxième niveau,


S'il n'est pas obtenu à partir du cache de deuxième niveau, recherchez-le à partir du cache de premier niveau. S'il n'est pas trouvé dans le cache de premier niveau, interrogez-le à partir du cache de premier niveau. base de données.


4.2 Configuration du cache de deuxième niveau mybatis

Ajoutez

SqlMapConfig. xml >


<setting name="cacheEnabled" value="true"/>

Pour ajouter une ligne à votre fichier de mappage Mapper : 8b0f252edde2ed6702a65a8dd34c5e13 cache de deuxième niveau.

4.3 Sérialisation Pojo du mappage des résultats de la requête


Le cache de deuxième niveau Mybatis doit implémenter l'interface Java.io.serializing

pour le résultat de la requête mapping pojo

, s'il n'est pas implémenté, lève une exception  :
org.apache.ibatis.cache.CacheException : erreur de sérialisation de l'objet Cause : java.io.NotSerializingException : com .sihai.mybatis.po.User


Le cache de deuxième niveau peut écrire des données de mémoire sur le disque. Il existe une sérialisation et une désérialisation des objets, l'interface java.io.serialisisable doit donc être implémentée.


Si le pojo du mappage des résultats inclut également du pojo, l'interface java.io.serializable doit être implémentée.

4.4 二级缓存禁用

对于变化频率较高的sql,需要禁用二级缓存:

在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。


<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">

4.5 刷新缓存

如果sqlsession操作commit操作,对二级缓存进行刷新(全局清空)。

设置statement的flushCache是否刷新缓存,默认值是true。

4.6 测试代码


//二级缓存的测试 
  @Test 
  public void testCache2() throws Exception { 
 
    SqlSession sqlSession1 = sqlSessionFactory.openSession(); 
    SqlSession sqlSession2 = sqlSessionFactory.openSession(); 
    SqlSession sqlSession3 = sqlSessionFactory.openSession(); 
    UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class); 
    UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class); 
    UserMapper userMapper3 = sqlSession3.getMapper(UserMapper.class); 
     
    //第一次查询用户id为1的用户 
    User user = userMapper1.findUserById(1); 
    System.out.println(user); 
    sqlSession1.close(); 
     
    //中间修改用户要清空缓存,目的防止查询出脏数据 
    /*user.setUsername("测试用户2"); 
    userMapper3.updateUser(user); 
    sqlSession3.commit(); 
    sqlSession3.close();*/ 
     
     
    //第二次查询用户id为1的用户 
    User user2 = userMapper2.findUserById(1); 
    System.out.println(user2); 
     
    sqlSession2.close(); 
     
 
  }

4.7 mybatis的cache参数

mybatis的cache参数只适用于mybatis维护缓存。

flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。

size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024。

readOnly(只读)属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。

如下例子:


<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>

这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会导致冲突。可用的收回策略有, 默认的是 LRU:

1. LRU – 最近最少使用的:移除最长时间不被使用的对象。

2. FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

3. SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。

4. WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

5 mybatis和ehcache缓存框架整合

mybatis二级缓存通过ehcache维护缓存数据。

5.1 分布缓存

将缓存数据数据进行分布式管理。

5.2 mybatis和ehcache思路

通过mybatis和ehcache框架进行整合,就可以把缓存数据的管理托管给ehcache。

在mybatis中提供一个cache接口,只要实现cache接口就可以把缓存数据灵活的管理起来。

mybatis中默认实现:

5.3 下载和ehcache整合的jar包

 

ehcache对cache接口的实现类:

5.4 配置ehcache.xml


<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"> 
  <!--diskStore:缓存数据持久化的目录 地址 --> 
  <diskStore path="F:\develop\ehcache" /> 
  <defaultCache  
    maxElementsInMemory="1000"  
    maxElementsOnDisk="10000000" 
    eternal="false"  
    overflowToDisk="false"  
    diskPersistent="true" 
    timeToIdleSeconds="120" 
    timeToLiveSeconds="120"  
    diskExpiryThreadIntervalSeconds="120" 
    memoryStoreEvictionPolicy="LRU"> 
  </defaultCache> 
</ehcache>

5.5 整合测试

在mapper.xml添加ehcache配置:


<!-- 开启二级缓存 --> 
  <!-- 单位:毫秒 --> 
  <cache type="org.mybatis.caches.ehcache.EhcacheCache"> 
    <property name="timeToIdleSeconds" value="12000"/> 
    <property name="timeToLiveSeconds" value="3600"/> 
    <!-- 同ehcache参数maxElementsInMemory --> 
    <property name="maxEntriesLocalHeap" value="1000"/> 
    <!-- 同ehcache参数maxElementsOnDisk --> 
    <property name="maxEntriesLocalDisk" value="10000000"/> 
    <property name="memoryStoreEvictionPolicy" value="LRU"/> 
  </cache>

6 二级缓存的应用场景

对查询频率高,变化频率低的数据建议使用二级缓存。

对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis二级缓存技术降低数据库访问量,提高访问速度,业务场景比如:耗时较高的统计分析sql、电话账单查询sql等。

实现方法如下:通过设置刷新间隔时间,由mybatis每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新间隔flushInterval,比如设置为30分钟、60分钟、24小时等,根据需求而定。

7 mybatis局限性

Le cache de deuxième niveau Mybatis n'est pas efficace pour la mise en cache au niveau des données à granularité fine, comme les exigences suivantes : mise en cache des informations sur le produit. En raison du grand nombre de visites de requêtes d'informations sur les produits, les utilisateurs doivent interroger les dernières informations sur les produits à chaque fois. À l'heure actuelle, si vous utilisez le cache de deuxième niveau de mybatis, vous ne pouvez pas obtenir que lorsqu'un produit change, seules les informations du cache du produit seront actualisées sans actualiser les informations des autres produits, Étant donné que la zone de cache de deuxième niveau de mybaits est divisée en unités de mappeurs, lorsqu'une information sur un produit change, toutes les données mises en cache de toutes les informations sur le produit seront effacées. La résolution de ces problèmes nécessite une mise en cache ciblée des données en fonction des besoins au niveau de la couche métier.

【Recommandations associées】

1. Recommandation spéciale : "php Programmer Toolbox" version V0.1 Télécharger

2. Tutoriel vidéo gratuit Java

3 Analyse complète des annotations 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