mybatis进阶3——缓存

测试代码MybatisCacheTest.java

1.一级缓存。

  • 一级缓存默认会启用,想要关闭一级缓存可以在select标签上配置flushCache="true"。
  • 一级缓存存在于SqlSession的生命周期中,在同一个SqlSession中查询时,Mybatis会把执行的方法和参数通过算法生成缓存的健值,将健值和查询结果存入一个Map对象中。如果同一个SqlSession中执行的方法和参数完全一致,那么通过算法会生成相同的健值,当Map缓存对象中已经存在该健值时,则会返回缓存中的对象
  • 任何insert/ update/ delete操作都会清空一级缓存
   @Test
    public void Test1LevelCache(){

        SqlSession session1 = sqlSessionFactory.openSession();
        TUserMapper userMapper1 = session1.getMapper(TUserMapper.class);
        String email = "qq.com";
        Byte sex = 1;
        List list1 = userMapper1.selectByEmailAndSex2(email, sex);
        System.out.println(list1.size());

        //增删改操作会清空一级缓存和二级缓存
//        TUser userInsert = new TUser();
//        userInsert.setUserName("test1");
//        userInsert.setRealName("realname1");
//        userInsert.setEmail("myemail1");
//        userMapper1.insert1(userInsert);

        //会走缓存
        List list2 = userMapper1.selectByEmailAndSex2(email, sex);
        System.out.println(list2.toString());

        HashMap map = new HashMap<>();
        map.put("email", email);
        map.put("sex", sex);
        //会走数据库
        List list3 = userMapper1.selectByEmailAndSex1(map);
        System.out.println(list3.toString());

        session1.close();

        //会走数据库
        SqlSession session2 = sqlSessionFactory.openSession();
        TUserMapper userMapper2 = session2.getMapper(TUserMapper.class);
        List list4 = userMapper2.selectByEmailAndSex2(email, sex);
        System.out.println(list2.toString());
        session1.close();
    }

2.二级缓存

  • 二级缓存存在于SqlSessionFactory的生命周期中,可以理解为跨SqlSession,缓存是以namespace为单位的,不同namespace下的操作互不影响
  • setting参数cacheEnabled是二级缓存的全局开关,默认值是true,若设为false,即使后面有二级缓存设置,也不会生效
  • 要开启二级缓存,需要在SQL映射文件中添加配置

上述配置的意思是:
1)映射语句文件中的所有select语句将会被缓存
2)映射语句文件中的所有insert/ update/ delete语句会刷新缓存
3)缓存使用FIFO算法来回收,还有LRU等算法
4)根据时间表flushInterval来刷新缓存
5)缓存会存储列表集合或对象(无论查询方法返回什么)的512个引用
6)缓存会被视为是只读的缓存

    @Test
    public void Test2LevelCache(){
        SqlSession session1 = sqlSessionFactory.openSession();
        TUserMapper userMapper1 = session1.getMapper(TUserMapper.class);
        String email = "qq.com";
        Byte sex = 1;
        List list1 = userMapper1.selectByEmailAndSex2(email, sex);
        System.out.println(list1.size());


//      TUser userInsert = new TUser();
//      userInsert.setUserName("test1");
//      userInsert.setRealName("realname1");
//      userInsert.setEmail("myemail1");
//      userMapper1.insert1(userInsert);

       //命中二级缓存
        List list2 = userMapper1.selectByEmailAndSex2(email, sex);
        System.out.println(list2.toString());
        session1.close();

       //命中二级缓存
        SqlSession session2 = sqlSessionFactory.openSession();
        TUserMapper userMapper2 = session2.getMapper(TUserMapper.class);
        List list3 = userMapper2.selectByEmailAndSex2(email, sex);
        System.out.println(list3.toString());
        session2.close();

        // 缓存是以namespace为单位的,会走数据库
        SqlSession session3 = sqlSessionFactory.openSession();
        TJobHistoryMapper userMapper3 = session3.getMapper(TJobHistoryMapper.class);
        List list4 = userMapper3.selectByEmailAndSex2(email, sex);
        System.out.println(list4.toString());
        session3.close();
    }

Tips:使用二级缓存容易出现脏读,建议避免使用二级缓存,在业务层使用可控制的缓存代替更好。


参考

  • 1)享学课堂Lison老师笔记

你可能感兴趣的:(mybatis进阶3——缓存)