Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung der Cache-Beispiele in mybatis

Detaillierte Erläuterung der Cache-Beispiele in mybatis

Y2J
Y2JOriginal
2017-05-13 10:40:541552Durchsuche

In diesem Artikel wird hauptsächlich der Abfrage-Cache des Mybatis-Tutorials (Cache der ersten Ebene, Cache der zweiten Ebene und integrierter Ehcache) vorgestellt, der einen bestimmten Referenzwert hat

1 Die Bedeutung des Caching

Legen Sie die von Benutzern häufig abgefragten Daten in den Cache (Speicher). Benutzer müssen die Daten nicht von der Festplatte (relationale Datenbankdatendatei) abfragen, sondern von die Cache-Abfrage, wodurch die Abfrageeffizienz verbessert und das Leistungsproblem von Systemen mit hoher Parallelität gelöst wird.

2 Mybatis-Persistenz-Layer-Cache

Mybatis bietet First-Level-Cache und Second-Level-Cache

Mybatis First-Level-Cache ist ein SqlSession-Level, der nur auf die Daten seines eigenen First-Level-Cache zugreifen kann ist ein Cache auf Mapper-Ebene. Der Cache auf Mapper-Ebene kann von verschiedenen SQL-Sitzungen gemeinsam genutzt werden.

3 Level 1 Cache

3.1 Prinzip

Wenn eine SQL-Abfrage zum ersten Mal ausgegeben wird, wird das SQL-Abfrageergebnis in den Cache der ersten Ebene von sqlsession geschrieben. Die im Cache verwendete Datenstruktur ist eine Karte144b4b4d8d0a132742ec1802e7d8024a

Schlüssel: Hashcode+ SQL+SQL-Eingabeparameter + Ausgabeparameter (die eindeutige Kennung von SQL)

Wert: Benutzerinformationen

Wenn dieselbe SQL-Sitzung dieselbe SQL ausgibt Auch hier wird es aus dem Cache abgerufen. Verwenden Sie nicht die Datenbank. Wenn zwischen zwei Malen ein Commit-Vorgang (Ändern, Hinzufügen, Löschen) stattfindet, wird der Cache-Bereich der ersten Ebene in dieser SQL-Sitzung gelöscht, und wenn Sie das nächste Mal zum Cache gehen, um ihn abzufragen, werden Sie wird es nicht abfragen können, also müssen Sie es von der Datenbank abfragen und es erneut von der Datenbank in den Cache abfragen.

Jede Abfrage fragt zuerst den Cache ab:


Wenn sie im Cache abgefragt wird, werden die Daten zwischengespeichert Direkt zurücksenden.

Wenn die Abfrage nicht im Cache gefunden werden kann, fragen Sie sie aus der Datenbank ab:

3.2 Level-1-Cache Konfiguration

Mybatis unterstützt standardmäßig den First-Level-Cache und erfordert keine Konfiguration.

Hinweis: Die Entwicklung des Mapper-Agenten wird nach der Integration von Mybatis und Spring durchgeführt. Mybatis und Spring generieren keine Mapper-Agenten und Vorlagen gemäß der Mapper-Vorlage. Schließen Sie die SQL-Sitzung am Ende einheitlich.

3.3 Level 1 Cache-Test


//一级缓存 
  @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 Level 2 Cache

4.1 Prinzip

Der Umfang des Caches der zweiten Ebene ist die Mapper-Ebene (der Mapper). ist derselbe

Namespace), Mapper erstellt eine Cache-Datenstruktur in Namespace-Einheiten und die Struktur ist mapf1e34d8162e3ac965af665baa7938918.

Überprüfen Sie bei jeder Abfrage zunächst, ob der Second-Level-Cache aktiviert ist, um zwischengespeicherte Daten aus der Datenstruktur des Second-Level-Cache abzurufen,


Wenn es nicht aus dem Cache der zweiten Ebene abgerufen wird, suchen Sie es im Cache der ersten Ebene. Wenn es nicht im Cache der ersten Ebene gefunden wird, fragen Sie es ab Datenbank.


4.2 mybatis Second-Level-Cache-Konfiguration

Fügen Sie

SqlMapConfig hinzu. xml >


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

So fügen Sie Ihrer Mapper-Zuordnungsdatei eine Zeile hinzu: 8b0f252edde2ed6702a65a8dd34c5e13 , die angibt, dass dieser Mapper die aktiviert Cache der zweiten Ebene.

4.3 Pojo-Serialisierung der Abfrageergebniszuordnung


Mybatis Second-Level-Cache muss die Java.io.serializable

-Schnittstelle für das Abfrageergebnis implementieren Zuordnungspojo

, wenn nicht implementiert, löst die Ausnahme org.apache.ibatis.cache.CacheException: Fehler beim Serialisieren des Objekts aus. Ursache: java.io.NotSerializableException: com .sihai.mybatis.po.User

Der Second-Level-Cache kann Speicherdaten auf die Festplatte schreiben. Es gibt eine Serialisierung und Deserialisierung von Objekten, daher muss die java.io.serializable-Schnittstelle implementiert werden.

Wenn das Pojo der Ergebniszuordnung auch Pojo enthält, muss die java.io.serializable-Schnittstelle implementiert werden.

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局限性

Der Second-Level-Cache von Mybatis eignet sich nicht für das differenzierte Caching auf Datenebene, z. B. für die folgenden Anforderungen: Zwischenspeicherung von Produktinformationen. Aufgrund der großen Anzahl von Produktinformationsabfragebesuchen müssen Benutzer bei jedem Aufruf die neuesten Produktinformationen abfragen Wenn Sie derzeit den Second-Level-Cache von mybatis verwenden, können Sie nicht erreichen, dass bei einer Produktänderung nur die Cache-Informationen des Produkts aktualisiert werden, ohne die Informationen anderer Produkte zu aktualisieren. Da der Cache-Bereich der zweiten Ebene von mybaits in Mapper-Einheiten unterteilt ist, werden alle zwischengespeicherten Daten aller Produktinformationen gelöscht, wenn sich Produktinformationen ändern. Die Lösung solcher Probleme erfordert eine gezielte Zwischenspeicherung von Daten basierend auf den Anforderungen auf der Geschäftsebene.

【Verwandte Empfehlungen】

1. Besondere Empfehlung: Version „php Programmer Toolbox“ V0.1 herunterladen

2. Kostenloses Java-Video-Tutorial

3. Umfassende Analyse von Java-Annotationen

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Cache-Beispiele in mybatis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn