mybatis缓存

mybatis缓存

什么是缓存

存在于内存中的临时数据。

为什么要使用缓存呢

减少和数据库的交互次数,提高执行效率。

什么样的数据能使用缓存,什么样的数据不能使用

适用于缓存:

1.经常查询并且不经常改变的。
2.数据的正确与否对最终结果影响不大的。

不适用于缓存:

1.经常改变的数据
2.数据的正确与否对最终结果影响很大的。例如:商品的库存,银行的汇率,股市的牌价。

Mybatis中的一级缓存和二级缓存

一级缓存:

它指的是Mybatis中SqlSession对象的缓存。

当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。

该区域的结构是一个Map。当我们再次查询同样的数据,mybatis会先去sqlsession中查询是否有,有的话直接拿出来用。

当SqlSession对象消失时,mybatis的一级缓存也就消失了。

@Test
    public void testFirstLevelCache() {
        User user1 = userDao.findById(41);
        System.out.println(user1);
        User user2 = this.userDao.findById(41);
        System.out.println(user2);

        System.out.println(user1 == user2);//true
    }

现在有这么一个测试方法,使用mybatis去查询user

在这里插入图片描述

发现两次查询的user1和user2是同一个对象,而且在第二次查询时,它没有再次去执行sql语句,而是直接输出结果了,原因就是因为mybatis中的sqlSession一级缓存机制。

只要 SqlSession 没有 flush 或 close,它就存在。

我们稍微做一些改变再次测试:

@Test
    public void testFirstLevelCache() {
        User user1 = userDao.findById(41);
        System.out.println(user1);

        sqlSession.close();
        //再次获取sqlSession对象
        sqlSession = factory.openSession();
        
//        sqlSession.clearCache();//此方法也可以清空缓存

        userDao = sqlSession.getMapper(UserDao.class);

        User user2 = this.userDao.findById(41);
        System.out.println(user2);

        System.out.println(user1 == user2);//false
    }

在这里插入图片描述

当我们中途close了一次sqlSession之后,就会发现,此时输出的是false,说明不再是同一个对象了,而且在第二次查询时重新执行了一次sql语句。

二级缓存:

它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。

二级缓存的使用步骤:

第一步:让Mybatis框架支持二级缓存(在配置文件Config.xml中配置)

<!--配置参数-->
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>

第二步:让当前的映射文件支持二级缓存(在持久层配置文件UserDao.xml中配置)

<!--开启user支持二级缓存-->
    <cache/>

第三步:让当前的操作支持二级缓存(在select标签中配置)

<select id="findById" resultType="user" parameterType="int" useCache="true">
        select * from USER where id = #{id}
</select>

测试二级缓存:

@Test
    public void testFirstLevelCache() {
        SqlSession sqlSession1 = factory.openSession();
        UserDao userDao1 = sqlSession1.getMapper(UserDao.class);
        User user1 = userDao1.findById(41);
        System.out.println(user1);
        sqlSession1.close();//一级缓存消失

        SqlSession sqlSession2 = factory.openSession();
        UserDao userDao2 = sqlSession2.getMapper(UserDao.class);
        User user2 = userDao2.findById(41);
        System.out.println(user2);
        sqlSession2.close();

        System.out.println(user1 == user2);//false
    }

在这里插入图片描述
因为二级缓存存储的是Map结构的数据而不是对象,每次需要数据时,就会把缓存里面的数据拿出来给新的对象,所以此时也是两个不同对象输出也是false。

但是我们发现,经过上面的测试,执行了两次查询,并且在执行第一次查询后,我们关闭了一级缓存,再去执行第二次查询时,我们发现并没有对数据库发出 sql 语句,所以此时的数据就只能是来自于我们所说的二级缓存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值