Mybatis——缓存

14.1一级缓存

默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)只在一次SqlSession中有效,也就是拿到连接到关闭连接这个区间。

测试步骤

1.开启日志

2.测试在一个Session中查询两次相同的记录

@Test
public void test(){
   SqlSession sqlSession = MybatisUtils.getSqlSession();
   UserMapper mapper = sqlSession.getMapper(UserMapper.class);
   User user1 = mapper.getUserById(1);
   System.out.println(user1);
   System.out.println("=================");
   User user2 = mapper.getUserById(1);
   System.out.println(user2);
   sqlSession.close();
}

3.查看日志输出

[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Opening JDBC Connection
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Created connection 1558021762.
[com.yl.dao.UserMapper.getUserById]-==> Preparing: select * from user where id = ?
[com.yl.dao.UserMapper.getUserById]-==> Parameters: 1(Integer)
[com.yl.dao.UserMapper.getUserById]-<==     Total: 1
User(id=1, name=张三, pwd=123456)
=================
User(id=1, name=张三, pwd=123456)

缓存失效的情况:

  • 增删改操作,可能会改变原来的数据,所以必定会刷新缓存

  • 查询不同的数据

  • 查询不同的Mapper.xml

  • 手动清理缓存

    在两次查询之间加入sqlSession.clearCache();

 

14.2二级缓存

二级缓存需要手动开启和配置,是基于namespace级别(一个mapper接口)的缓存

工作机制:

  • 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中

  • 如果当前会话关闭了,这个会话对应的一级缓存就没有了,一级缓存中的数据被保存到二级缓存中

  • 新的会话查询信息,就可以从二级缓存中获取

  • 不同的mapper查出的数据会放在自己对应的缓存(map)中

     

步骤:

1.开启全局缓存

cacheEnabled:全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。

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

2.

<mapper namespace="com.yl.dao.UserMapper">
   <!--在当前mapper.xml文件中使用二级缓存-->
   <cache/>

   <select id="getUserById" resultType="User">
      select * from user where id = #{id}
   </select>

</mapper>

或者

<mapper namespace="com.yl.dao.UserMapper">
<!--使用二级缓存-->
   <select id="getUserById" resultType="User" useCache="true">
      select * from user where id = #{id}
   </select>

</mapper>

高级设置

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

FIFO : first in first out 先进先出

3.测试:

@Test
public void test(){
   SqlSession sqlSession = MybatisUtils.getSqlSession();
   SqlSession sqlSession2 = MybatisUtils.getSqlSession();

   UserMapper mapper = sqlSession.getMapper(UserMapper.class);
   UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);

   User user = mapper.getUserById(1);
   System.out.println(user);
   System.out.println("=================");

   sqlSession.close();

   User user2 = mapper2.getUserById(1);//只查询一次
   System.out.println(user2);
   System.out.println(user==user2);//true
   sqlSession2.close();
}

问题:

Cause: java.io.NotSerializableException: com.yl.pojo.User

我们需要将实体类序列化,否则就会报错

public class User implements Serializable

 

小结

  • 只要开启了二级缓存,在同一个Mapper下就有效

  • 所有的数据都会先放在一级缓存中

  • 只有当会话提交或者关闭的时候才会提交到二级缓存中

  • 用户查询,首先看二级缓存,二级缓存没有进入一级缓存,没有才查询数据库

 

14.3自定义缓存

导包

<!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache -->
<dependency>
   <groupId>org.mybatis.caches</groupId>
   <artifactId>mybatis-ehcache</artifactId>
   <version>1.1.0</version>
</dependency>

mapper.xml

<mapper namespace="com.yl.dao.UserMapper">
   <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

   <select id="getUserById" resultType="User" useCache="true">
      select * from user where id = #{id}
   </select>

</mapper>

新建ehcache.properties

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
        updateCheck="false">

  <diskStore path="./tmpdir/Tmp_EhCache"/>

  <defaultCache
          eternal="false"
          maxElementsInMemory="10000"
          overflowToDisk="false"
          diskPersistent="false"
          timeToIdleSeconds="1800"
          timeToLiveSeconds="259200"
          memoryStoreEvictionPolicy="LRU"/>

  <cache
          name="cloud_user"
          eternal="false"
          maxElementsInMemory="5000"
          overflowToDisk="false"
          diskPersistent="false"
          timeToIdleSeconds="1800"
          timeToLiveSeconds="1800"
          memoryStoreEvictionPolicy="LRU"/>
</ehcache>

 

目前流行Redis数据库来做缓存

posted @ 2020-08-31 20:01  Fabulo  阅读(134)  评论(0)    收藏  举报