mybatis的缓存

目录

1.什么是缓存

2.mybatis的缓存

2.1一级缓存

 2.2 二级缓存

2.2.1 开启二级缓存

2.2.2 在映射文件中使用二级缓存

2.2.3 实体一定要实现序列化接口

 2.2.4 二级缓存测试


1.什么是缓存

        缓存就是数据交换的缓冲区,当某一硬件要读取数据时,会首先从缓存中查找需要的数据,如果找到了则直接执行,找不到的话则从内存中找。由于缓存的运行速度比内存快得多,故缓存的作用就是帮助硬件更快地运行。

        例如 mysql数据库中的数据存在表内也就是在磁盘上。 查询时程序IO读取磁盘的数据,添加时io向磁盘添加数据。

        经常查询并且不经常改变的,数据的正确与否对最终结果影响不大的; 这些数据适合放在缓存中。经常改变的数据;数据的正确与否对最终结果影响很大的;---数据安全性要求不高。例如:商品的库存,银行的汇率,股市的牌价; 这些数据不适合放在缓存区。

2.mybatis的缓存

        MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。

        mybatis支持两种缓存:

                (1)一级缓存----基于SqlSession级别的缓存,底层就是一个hashmap。默认一级缓存是开启的,不能关闭。同一个sqlsession中执行相同的sql查询(相同的sql和参数),第一次会去查询数据库并写到缓存中,第二次从一级缓存中取。当执行SQL时候两次查询中间发生了增删改的操作,则SQLSession的缓存会被清空,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。

                (2)二级缓存--基于SqlSessionFactory级别的缓存,它可以做到多个SqlSession共享数据。默认它是关闭。需要手动开启。 要启用全局的二级缓存,需要在你的 SQL 映射文件中添加一行语句。

2.1一级缓存

        一级缓存基于sqlSession完成的一级缓存,第一次查询编号=2的用户信息--缓存不能命中,则向数据库查询发送sql语句、把查询的结果放入缓存中。当sqlSession不关闭时,不需要再在数据库调数据,而是在缓存中直接调取。下面是测试类及控制台显示只调取一次sql语句。


    @Test
    public void testSession(){
        User user = userMapper.getUser(2);
        User user1 = userMapper.getUser(2);

    }

2022-06-06 19:07:21,399 [main] DEBUG [com.qy151wd.mapper.UserMapper.getUser] - ==>  Preparing: select * from tb_user where id=?
2022-06-06 19:07:21,448 [main] DEBUG [com.qy151wd.mapper.UserMapper.getUser] - ==> Parameters: 2(Integer)
2022-06-06 19:07:21,494 [main] DEBUG [com.qy151wd.mapper.UserMapper.getUser] - <==      Total: 1

        当一个sqlSession关闭时,开启另一个sqlSession语句会重新进行数据库数据调取,会出现两条调取数据库的信息。

 @Test
    public void testSession(){
        User user = userMapper.getUser(2);
        User user1 = userMapper.getUser(2);
       sqlSession.close();
       SqlSession sqlSession1=sqlSessionFactory.openSession();
        UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
        mapper1.getUser(2);

    }

2022-06-06 21:03:16,530 [main] DEBUG [com.qy151wd.mapper.UserMapper.getUser] - ==>  Preparing: select * from tb_user where id=?
2022-06-06 21:03:16,576 [main] DEBUG [com.qy151wd.mapper.UserMapper.getUser] - ==> Parameters: 2(Integer)
2022-06-06 21:03:16,618 [main] DEBUG [com.qy151wd.mapper.UserMapper.getUser] - <==      Total: 1
2022-06-06 21:03:16,623 [main] DEBUG [com.qy151wd.mapper.UserMapper.getUser] - ==>  Preparing: select * from tb_user where id=?
2022-06-06 21:03:16,624 [main] DEBUG [com.qy151wd.mapper.UserMapper.getUser] - ==> Parameters: 2(Integer)
2022-06-06 21:03:16,628 [main] DEBUG [com.qy151wd.mapper.UserMapper.getUser] - <==      Total: 1

 2.2 二级缓存

2.2.1 开启二级缓存

<settings>
        <!--开启二级缓存(conf.xml内)-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

2.2.2 在映射文件中使用二级缓存

<!--使用二级缓存 这里面的所有查询都使用了二级缓存(对应mapper.xml内)-->
  <cache/>
<!--部分开启二级缓存,此处不使用二级缓存-->
<select id="getUser" parameterType="int" resultType="com.qy151wd.entity.User" useCache="false">
        select * from tb_user where id=#{id}
    </select>

2.2.3 实体一定要实现序列化接口

 2.2.4 二级缓存测试

        如果开启了二级缓存,那么在关闭sqlsession后(close),才会把该sqlsession一级缓存中的数据添加到namespace的二级缓存中。所查询的结果会放入一级缓存和二级缓存,若二级缓存能命中,则直接从二级缓存中调取数据,若不能命中,会到一级缓存中去查看是否命中,若能则直接调取数据,若不能则进入数据库调取。查询顺序是二级缓存、一级缓存、数据库。

@Test
    public void testSessionSecond(){
        User user = userMapper.getUser(2);
        User user1 = userMapper.getUser(2);
        sqlSession.close();
        SqlSession sqlSession1=sqlSessionFactory.openSession();
        UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
        mapper1.getUser(2);

    }

2022-06-06 19:51:17,391 [main] DEBUG [com.qy151wd.mapper.UserMapper] - Cache Hit Ratio [com.qy151wd.mapper.UserMapper]: 0.0
2022-06-06 19:51:18,516 [main] DEBUG [com.qy151wd.mapper.UserMapper.getUser] - ==>  Preparing: select * from tb_user where id=?
2022-06-06 19:51:18,564 [main] DEBUG [com.qy151wd.mapper.UserMapper.getUser] - ==> Parameters: 2(Integer)
2022-06-06 19:51:18,593 [main] DEBUG [com.qy151wd.mapper.UserMapper.getUser] - <==      Total: 1
2022-06-06 19:51:18,597 [main] DEBUG [com.qy151wd.mapper.UserMapper] - Cache Hit Ratio [com.qy151wd.mapper.UserMapper]: 0.0
2022-06-06 19:51:18,604 [main] WARN  [org.apache.ibatis.io.SerialFilterChecker] - As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctx=javase15&id=GUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66
2022-06-06 19:51:18,607 [main] DEBUG [com.qy151wd.mapper.UserMapper] - Cache Hit Ratio [com.qy151wd.mapper.UserMapper]: 0.3333333333333333

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值