Mybatis的二级缓存(一)

引子:
再上一篇文章中介绍了一级缓存,但是也可以看出一些一级缓存的局限,一是一级缓存的范围是session级别的,不同的session之间无法实现缓存共享,二是一级缓存是放到内存中的一旦数据过大有可能会出现内存不足的情况。为此mybatis还有一种二级缓存机制。

二级缓存
首先二级缓存的范围要比session大属于mapper级别的,即在同一个namespace下的缓存,因此可以实现不同session之间共享缓存,其次二级缓存既可以利用Mybatis自带的PerpetualCache ,也可利用其他缓存框架(如EhCache),前提是要实现mybatis中的Cache接口,同时缓存不一定会放在内存中,所以被缓存的数据要声明可序列化.
二级缓存的条件:

  1. settings中开启二级缓存,cacheEnabled为true
    这里写图片描述
  2. 2级缓存的类型要实现序列化接口Serializable
    这里写图片描述
  3. mapper文件设置支持二级缓存
    这里写图片描述
  4. select标签useache=true(默认为true)
    这里写图片描述
  5. session提交或关闭后才会将session中的一级缓存刷入到二级缓存
    OK我们可以先来看一看运行代码
        SqlSession session =factory.openSession();
        SqlSession session2 = factory.openSession();
        BbsuserMapper bbsuserMapper1 = session.getMapper(BbsuserMapper.class);

        Bbsuser bbsuser = new Bbsuser();


        System.out.println("二级缓存");
        BbsuserMapper bbsuserMapper2 = session2.getMapper(BbsuserMapper.class);
        bbsuser.setName("李四");
        bbsuser.setPassword("456");
        System.out.println(bbsuserMapper2.searchBbuser(bbsuser));
        //关闭或者提交session后,一级缓存会到二级缓存中
        session2.commit();
        session2.close();
        System.out.println("调用其他session");
        System.out.println(bbsuserMapper1.searchBbuser(bbsuser));
        session.commit();
        session.close();

这里写图片描述
可以看到,当我们关闭了session2后,session依然找到了缓存这边是二级缓存,也就是mapper级别的缓存.但是如果在session2关闭前,执行了更新等操作时会清空一级缓存也就会导致没有将一级缓存放入到二级缓存.
这里写图片描述
可以看到在session2执行了插入语句后,二级缓存里并没有这个数据了..

二级缓存的问题
前面也说过了二级缓存是mapper级别的缓存,因此一旦有其他的mapper对数据库里通样的执行了更新等操作的话,很有可能会造成数据的不一致.这里写了一个测试方法:

public void badAche() {
        SqlSession session =factory.openSession();
        SqlSession session2 = factory.openSession();
        BbsuserMapper bbsuserMapper1 = session.getMapper(BbsuserMapper.class);

        Bbsuser bbsuser = new Bbsuser();
        bbsuser.setName("张三");
        bbsuser.setPassword("123");
        //查询一个用户下收到的消息数量
        System.out.println("二级缓存问题:\n"+bbsuserMapper1.searchBbuser(bbsuser).getMessage().size());
        session.close();
        MessageMapper mapper = session2.getMapper(MessageMapper.class);
        BbsuserMapper bbsuserMapper2 = session2.getMapper(BbsuserMapper.class);
        //利用其他mapper下插入一个消息
        mapper.insertMessage(new Message("张三", "李四", "问题", new Date(), "ss"));
        System.out.println("在不同namespace下执行了更新操作\n");
        session2.commit();
        System.out.println("二级缓存仅针对一个namespace下");
        System.out.println(bbsuserMapper2.searchBbuser(bbsuser).getMessage().size());
        session2.close();
    }

结果
这里写图片描述
可以看到利用其他的MessageMapper插入后,BbsuserMapper 并不会刷新二级缓存,而这也是比较局限的地方,但是我们可以通过配置定时刷新二级缓存来减少这样的数据不一致

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值