Mybatis缓存机制
缓存机制
什么是缓存
缓存是存在于内存中的临时数据。
使用缓存减少和数据库的交互次数,提高执行效率。
一级缓存
mybatis中默认就有一级缓存,一级缓存作用域是sqlsession级别的,同一个sqlsession中执行相同的sql查询(相同的sql和参数),第一次会去查询数据库并写到缓存中,第二次从一级缓存中取。
一级缓存是基于 PerpetualCache 的 HashMap 本地缓存,默认打开一级缓存。
缓存失效的情况
   缓存失效的情况:
        1、查询不同的东西
        2、增删改操作,会改变原来的数据,所以必定会刷新缓存
        3、查询不同的Mapper.xml文件
        4、手动清理缓存
@Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.queryUserById(1);
        System.out.println(user);
        System.out.println("=============================");
        User user1 = mapper.queryUserById(2);
        System.out.println(user1);
        System.out.println(user==user1);
        sqlSession.close();
    }

很明显,当查询不同的东西是,第二就会从数据库中再次去查询
@Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.queryUserById(1);
        System.out.println(user);
        System.out.println("=============================");
        User user1 = mapper.queryUserById(1);
        System.out.println(user1);
        System.out.println(user==user1);
        sqlSession.close();
    }

当查相同的东西时,就会从缓存里直接拿取,而不是再去查询一遍
二级缓存
它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。
<!--    在当前Mapper.xml中使用二级缓存-->
<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>
这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。
FIFO – 先进先出:按对象进入缓存的顺序来移除它们
@Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        SqlSession sqlSession1 = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.queryUserById(1);
        System.out.println(user);
//        mapper.updateUser(new User(2,"abc","123"));
        sqlSession.close();
       
//        sqlSession.clearCache();//手动清理缓存
        System.out.println("=============================");
        UserMapper mapper1= sqlSession1.getMapper(UserMapper.class);
        User user1 = mapper1.queryUserById(1);
        System.out.println(user1);
        System.out.println(user==user1);
        sqlSession1.close();
    }

当查完第一次后,sqlSession关闭,会把查询的数据会放在二级缓存中,第二次查询,不需要重新再查,可以直接使用
@Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        SqlSession sqlSession1 = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.queryUserById(1);
        System.out.println(user);
        mapper.updateUser(new User(2,"abc","123"));
        sqlSession.close();
       
//        sqlSession.clearCache();//手动清理缓存
        System.out.println("=============================");
        UserMapper mapper1= sqlSession1.getMapper(UserMapper.class);
        User user1 = mapper1.queryUserById(1);
        System.out.println(user1);
        System.out.println(user==user1);
        sqlSession1.close();
    }

当第一次查询完后,因为执行了修改,所以会把一级缓存清空,所以二级缓存中无数据,所以第二次就需要再次从数据库中查找
也可以自定义二级缓存
<!--    ehcache缓存-->
    <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
需要配置ehcache.xml
<?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>
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号