Você sabe algo sobre o cache Mybatis?

Como o cache é implementado

  • Cache de nível 1

  • Cache secundário

Prática de caso

1. Cache de nível 1

Cache local HashMap baseado em PerpetualCache (mybatis implementa internamente a interface de cache), e seu escopo de armazenamento é Sessão. Após a liberação ou fechamento da Sessão, todos os Caches na Sessão serão esvaziados;

2. Cache secundário

O mecanismo do cache de primeiro nível é o mesmo, o padrão também é o armazenamento HashMap do PerpetualCache, a diferença é que seu escopo de armazenamento é Mapper (Namespace), e a fonte de armazenamento pode ser customizada, como Ehcache;

Para o mecanismo de atualização de dados de cache, quando uma operação C / R / U / D é realizada em um determinado escopo (Sessão de cache de primeiro nível / Namespaces de cache de segundo nível), todos os caches selecionados sob este escopo serão limpos por padrão.

Se o segundo cache estiver habilitado, primeiro consulte os dados do segundo cache, se o segundo cache os tiver, obtenha os dados do segundo cache, se o segundo cache não tiver, verifique se há dados de cache do primeiro cache, se o primeiro cache não tiver, consulte Banco de dados .

3. Limitações do cache secundário

O cache de segundo nível Mybatis não é bom para o cache de nível de dados refinado. Para armazenar mais dados em cache ao mesmo tempo, como os seguintes requisitos: armazenar em cache informações do produto, devido ao grande número de visitas a consultas de informações do produto, mas os usuários são obrigados a Pode consultar as informações mais recentes do produto. Neste momento, se você usar o cache secundário de mybatis, não será possível atualizar apenas as informações de cache deste produto e não as informações de outros produtos quando um produto muda, porque a área de cache secundária de mybaits é baseada no mapeador. Dividido, quando as informações de um produto são alteradas, todos os dados em cache das informações do produto serão apagados

4. Cache de nível 1 (ativado por padrão)

Mybatis fornece cache de primeiro nível por padrão, e o escopo do cache é sqlSession. Na mesma SqlSession, execute a mesma consulta sql duas vezes e não faça mais consultas no banco de dados pela segunda vez.

Princípio: O cache de primeiro nível usa armazenamento Hashmap.Quando mybatis executa uma consulta, ele fará uma consulta do cache, se não houver nenhuma consulta do banco de dados no cache. Se o SqlSession executar clearCache () commit ou adicionar operação de modificação de exclusão, limpe o cache.

Existe por padrão, basta entender o resultado da observação

a. Existência de cache (sessão não enviada)

@Test 

public void test01() { 

    SqlSession sqlSession=sqlSessionFactory.openSession();  

    AccountDao accountDao=sqlSession.getMapper(AccountDao.class);  

    Account account=accountDao.queryAccountById(1); 

    System.out.println(account); 

    accountDao.queryAccountById(1);  

} 

O log só imprime um sql

Você sabe algo sobre o cache Mybatis?

b. Atualize o cache

Os dados em cache são atualizados quando a sessão é enviada

@Test 
public void test02() { 
    SqlSession sqlSession=sqlSessionFactory.openSession();  
    AccountDao accountDao=sqlSession.getMapper(AccountDao.class);  
    Account account=accountDao.queryAccountById(1); 
    System.out.println(account); 
    sqlSession.clearCache(); 
    accountDao.queryAccountById(1);  
} 

efeito:

Você sabe algo sobre o cache Mybatis?

5. Cache secundário

O cache de primeiro nível está no mesmo sqlSession e o cache de segundo nível está no mesmo namespace, portanto, diferentes sqlsessions com o mesmo namespace podem usar o cache de segundo nível.

cenas a serem usadas

  • Para dados com alta frequência de consulta e baixa frequência de alteração, é recomendável usar o cache secundário.
  • Para pedidos de consulta que são acessados ​​com frequência e os usuários não têm grandes requisitos para resultados de consulta em tempo real, a tecnologia de cache secundário mybatis pode ser usada para reduzir o acesso ao banco de dados e aumentar a velocidade de acesso. Cenários de negócios como: análise estatística demorada sql, contas de telefone Consultar sql etc.

Configuração de arquivo global (mybatis.xml)

<setting name="cacheEnabled" value="true"/> 
Mapper.xml 中加入 :打开该 mapper 的二级缓存 

<!-- 开启该 mapper 的二级缓存 --> 

<cache/>

Atributos comuns da tag de cache

<cache  

eviction="FIFO" <!--回收策略为先进先出--> 

flushInterval="60000" <!--自动刷新时间 60s--> 

size="512" <!--最多缓存 512 个引用对象--> 

readOnly="true"/> <!--只读--> 

Descrição:

  1. Todas as instruções de seleção no arquivo de instrução de mapeamento serão armazenadas em cache.
  2. Todas as instruções de inserção, atualização e exclusão no arquivo de instrução mapeada irão atualizar o cache.
  3. O cache usará o algoritmo menos usado recentemente (LRU, usado menos recentemente) para recuperar.
  4. O cache será atualizado de acordo com o intervalo de tempo especificado.
  5. O cache irá armazenar 1024 objetos

O objeto PO deve suportar serialização

public class User implements Serializable { 

} 

Desligue o cache de instrução específica no Mapper

Use useCache: o padrão é verdadeiro

<select id="findUserByid" parameterType="int" resultType="User"  

useCache="false"> 

    SELECT * FROM user WHERE id=#{id} 

</select> 

Atualize o cache secundário

Ao operar a instrução CUD, o cache de segundo nível será forçado a atualizar, ou seja, o flushCache padrão = "true". Se você quiser desligar a configuração para flushCache = "false", não é recomendado desligar a atualização, porque a atualização da operação exclui a modificação e é fácil sujar após o fechamento dados.

Teste de cache secundário:

@Test 

public void test03() { 

    SqlSession sqlSession=sqlSessionFactory.openSession();  

    AccountDao accountDao=sqlSession.getMapper(AccountDao.class);  

    Account account=accountDao.queryAccountById(1); 

    System.out.println(account); 

    sqlSession.close(); 

    SqlSession sqlSession2=sqlSessionFactory.openSession(); 

    AccountDao accountDao2=sqlSession2.getMapper(AccountDao.class);  

    accountDao2.queryAccountById(1); 

    sqlSession.close(); 

} 

efeito:

Você sabe algo sobre o cache Mybatis?

Expandir

Cache distribuído ehcache

Se houver vários servidores, o cache distribuído não será usado e os dados em cache serão armazenados separadamente em cada servidor, o que não é conveniente para o desenvolvimento do sistema. Portanto, um cache distribuído deve ser usado para gerenciar centralmente os dados em cache. Portanto, use o ehcache memcached redis

O Mybatis em si não pode alcançar o cache distribuído, então ele precisa ser integrado com o framework de cache distribuído. EhCache é uma estrutura de cache em processo Java pura, que é rápida e capaz; Ehcache é um cache distribuído Java de código aberto amplamente usado. Principalmente para cache de uso geral, Java EE e contêineres leves. Ele possui recursos como memória e armazenamento em disco, carregador de cache, extensão de cache, manipulador de exceção de cache, filtro de servlet de cache gzip e suporta REST e SOAP api.

Dependência de Jar

<dependency> 

    <groupId>net.sf.ehcache</groupId> 

    <artifactId>ehcache-core</artifactId> 

    <version>2.4.4</version> 

</dependency> 

<dependency> 

    <groupId>org.mybatis.caches</groupId> 

    <artifactId>mybatis-ehcache</artifactId> 

    <version>1.0.3</version> 

</dependency> 

Configuração de interface de cache

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/> 

Adicione ehcache.xml sob src (não é necessário, nenhuma configuração padrão é usada)

<?xml version="1.0" encoding="UTF-8"?> 

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xsi:noNamespaceSchemaLocation="../bin/ehcache.xsd"> 

<!-- 

name:Cache 的唯一标识 

maxElementsInMemory:内存中最大缓存对象数 

maxElementsOnDisk:磁盘中最大缓存对象数,若是 0 表示无穷大 

eternal:Element 是否永远不过期,如果为 true,则缓存的数据始终有效,如果为 false 

那么还要根据 timeToIdleSeconds,timeToLiveSeconds 判断 

overflowToDisk:配置此属性,当内存中 Element 数量达到 maxElementsInMemory 时, 

Ehcache 将会 Element 写到磁盘中 

timeToIdleSeconds:设置 Element 在失效前的允许闲置时间。仅当 element 不是永久有效 

时使用,可选属性,默认值是 0,也就是可闲置时间无穷大 

timeToLiveSeconds:设置 Element 在失效前允许存活时间。最大时间介于创建时间和失效 

时间之间。仅当 element 不是永久有效时使用,默认是 0.,也就是 element 存活时间无穷 

大 

diskPersistent:是否缓存虚拟机重启期数据 

diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是 120 秒 

diskSpoolBufferSizeMB:这个参数设置 DiskStore(磁盘缓存)的缓存区大小。默认是 

30MB。每个 Cache 都应该有自己的一个缓冲区 

memoryStoreEvictionPolicy:当达到 maxElementsInMemory 限制时,Ehcache 将会根据 

指定的策略去清理内存。默认策略是 LRU(最近最少使用)。你可以设置为 FIFO(先进先 

出)或是 LFU(较少使用) 

--> 

<defaultCache overflowToDisk="true" eternal="false"/> 

<diskStore path="D:/cache" /> 

<!-- 

<cache name="sxtcache" overflowToDisk="true" eternal="false" 

timeToIdleSeconds="300" timeToLiveSeconds="600" maxElementsInMemory="1000" 

maxElementsOnDisk="10" diskPersistent="true"  

diskExpiryThreadIntervalSeconds="300" 

diskSpoolBufferSizeMB="100" memoryStoreEvictionPolicy="LRU" /> 

--> 

teste:

@Test 

public void test04() { 

    SqlSession sqlSession=sqlSessionFactory.openSession();  

    AccountDao accountDao=sqlSession.getMapper(AccountDao.class);  

    Account account=accountDao.queryAccountById(1); 

    System.out.println(account); 

    sqlSession.close(); 

    SqlSession sqlSession2=sqlSessionFactory.openSession(); 

    AccountDao accountDao2=sqlSession2.getMapper(AccountDao.class);  

    accountDao2.queryAccountById(1); 

    sqlSession.close(); 

} 

Efeito:
Taxa de acertos do cache [com.xxx.dao.AccountDao]: 0,5

Acho que você gosta

Origin blog.51cto.com/15047271/2569700
Recomendado
Clasificación