栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Mybatis】一级缓存

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Mybatis】一级缓存

目录

1.什么是缓存[Cache ]?

2.为什么使用缓存?(缓存的意义,目的)

3.什么样的数据能使用缓存?

4.Mybatis缓存

5.Mybatis缓存的适用场景以及测试

一级缓存

6.一级缓存失效的四种情况:

1.一次性查询不同的对象

2.增删改会刷新缓存

3.运行不同的mapper

4.手动清理缓存

总结


1.什么是缓存[Cache ]?


缓存是存在内存中的临时数据。


将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。


2.为什么使用缓存?(缓存的意义,目的)


减少和数据库的交互次数,减少系统开销,提高系统效率。

3.什么样的数据能使用缓存?


经常查询并且不经常改变的数据。(说白了就是查的数据)

反过头来说,经常改变的数据(也就是增删改的数据)就不适合作为缓存的数据,因为它如果改变一次就缓存一次就会造成系统开销,实属没必要。

4.Mybatis缓存


MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。

 MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存


 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)。

二级缓存需要手动开启和配置,他是基于namespace级别的缓存。


为了提高扩展性,MyBatis定义了缓存接口cache。我们可以通过实现Cache接口来自定义二级缓存

5.Mybatis缓存的适用场景以及测试

一级缓存

让我们来测试一级缓存:

public interface UserMapper {
    List getUserById(@Param("id")int id);
}

    
        select * from user where id = #{id}
    
 @Test
    public void Test(){
        SqlSession sqlSession = MyUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user1 = mapper.getUserById(1);
        System.out.println(user1);
        System.out.println("============");
        User user2 = mapper.getUserById(1);
        System.out.println(user2);
        System.out.println(user1==user2);
        sqlSession.close();
    }

 可以发现sql只走了一次,这说明当我们第一次查第id为1的User时,只要他没有被改变,就会被存入一级缓存(本地缓存)中,那么如果再查一次它,就不用去执行sql了,而是从一级缓存中去取。这就是一级缓存的作用之一。

比如下面这个例子:我们修改了Test方法,先查id为1的user1,然后查id为2的user2,最后查id为1user3(user3==user1)

    @Test
    public void Test(){
        SqlSession sqlSession = MyUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user1 = mapper.getUserById(1);
        System.out.println(user1);
        System.out.println("============");
        User user2 = mapper.getUserById(2);
        System.out.println(user2);
        System.out.println(user1==user2);
        System.out.println("============");
        User user3 = mapper.getUserById(1);
        System.out.println(user3);
        System.out.println(user1==user3);
        sqlSession.close();
    }

 

 至于蓝色标记的id为2的user,他并不影响user1存入缓存,为user3去取提供方便的事实。因此也验证了我们那句话:只要他没有被改变(刷新缓存除外),就会被存入一级缓存(本地缓存)中。

6.一级缓存失效的四种情况:

1.一次性查询不同的对象

比如我先查了id为1的user,我又查询了id为2的user,想都不用想,肯定不会缓存。

2.增删改会刷新缓存
public void Test1(){
        SqlSession sqlSession = MyUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user1 = mapper.getUserById(1);
        System.out.println(user1);
        System.out.println("==============");
        mapper.updateUserById(new User(2,"kxy","1434134"));
        System.out.println("==============");
        User user2 = mapper.getUserById(1);
        System.out.println(user2);
        System.out.println(user1==user2);
        sqlSession.commit();
        sqlSession.close();
    }

 

像这种情况,增删改操作导致的数据可能会改变原来的数据,即便改变的不是当前对象,也会刷新缓存,从而导致第二次读取执行sql从数据库里重新查了一次。重新开辟了地址给user2,所以use1==user2是false,即他们不是同一个对象。其本质:地址不同,值相同。

由此可见:增删改会刷新缓存,刷新缓存产生新的对象。

3.运行不同的mapper

因为一个mapper对应一个sqlsession(sqlsession.getMapper),而一级缓存的作用范围只在sqlsession(从sqlsession创建到sqlsession关闭),因此运行不同的mapper当然不会实现一级缓存。

4.手动清理缓存
@Test
    public void Test1(){
        SqlSession sqlSession = MyUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user1 = mapper.getUserById(1);
        System.out.println(user1);
        sqlSession.clearCache();
        System.out.println("==============");
        User user2 = mapper.getUserById(1);
        System.out.println(user2);
        System.out.println(user1==user2);
        sqlSession.close();
    }

 显然sql运行了两次,第二次没有从缓存中拿,是因为缓存被清理了。false是因为从数据库中又查了一遍,从jdbc的角度来讲,他每次查询都产生一个resultset类型的对象,因此对象肯定是新的对象,其本质:地址不同,值相同。

由此可见:清空缓存会产生新的对象。

总结

1.只要他没有被改变(刷新缓存除外),就会被存入一级缓存(本地缓存)中。

2.增删改会刷新缓存,刷新缓存产生新的对象。

3.清空缓存会产生新的对象。


一级缓存失效的四种情况:

1.一次性查询不同的对象。

2.增删改会刷新缓存

3.运行不同的mapper

4.手动清理缓存

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1010163.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号