Mybatis(四) Mybatis缓存

4.1 Mybatis缓存概念

??缓存就是内存中的数据,常常来自对数据库查询结果的保存,使用缓存,我们可以避免频繁的与数据进行交互,进而提高响应速度。
Mybatis 也提供了对缓存的支持,分为一级缓存和二级缓存,通过下图来理解:

  1. 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession2直接的缓存区域(HashMap)是互相不影响。
  2. 二级缓存是Mapper级别的缓存,多个SqlSession去操作同一个Mapper查询的sql语句,多个sqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

4.2 一级缓存

4.2.1 一级缓存案例

??mybatis一级缓存是默认开启的

 @Test
 public void firstLevelCache() throws IOException {
     InputStream resourceAsSteam = Resources.getResourceAsStream("sqlMapperConfig.xml");
     SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsSteam);
     SqlSession sqlSession = sqlSessionFactory.openSession();
     UserDao userDao = sqlSession.getMapper(UserDao.class);
    User byUserId = userDao.findByUserId(1);
    User user = userDao.findByUserId(1);
    System.out.println(byUserId == user);
}
#输出结果 true

??第一次查询是会打出查询日志,第二次不会,而且两次查出的user地址是同一个,证明了一级缓存开启了。

 @Test
    public void firstLevelCache() throws IOException {
        InputStream resourceAsSteam = Resources.getResourceAsStream("sqlMapperConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsSteam);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        User byUserId = userDao.findByUserId(1);
				//添加修改操作
        User upuser = new User();
        upuser.setUsername("helo");
        upuser.setId(1);
        userDao.updateUser(upuser);
        sqlSession.commit();

        User user = userDao.findByUserId(1);
        System.out.println(byUserId == user);
    }
 #输出结果  false

4.2.2 总结

  1. 第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户信息。得到用户信息,将用户信息存储到一级缓存中
  2. 如果中间SqlSession去执行commit操作(执行插入、更新、删除),则会清空SqlSession中的一级缓存,这样做的目的是为了让缓存中存储的是最新的信息,避免脏读
  3. 第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。

4.2.3 一级缓存解析

??一级缓存到底是什么?一级缓存什么时候被创建的、一级缓存的工资流程是怎么样的?

4.3 二级缓存

??二级缓存的原理和一级缓存原理一样,第一次查询会将数据放入缓存中,然后第二次查询则会直接去缓存中取。但是一级缓存是基于SqlSession的,而二级缓存是基于mapper文件的namespace的,也就是说多个SqlSession可以共享一个mapper中的二级缓存区域,并且如果两个mapper的namespace相同,即使是两个mapper,那么这两个mapper中执行SQL查询到的数据也将存在相同的二级缓存区域中。

4.3.1 开启二级缓存

二级缓存需要手动开启,sqlMapperConfig.xml中配置如下:

<settings>
	<settting name=cacheEnabled" value="true" />
<settings>

在UserMapper.xml中添加

? //二级缓存默认实现的是?PerpetualCache 类

@Test
public` `void` `testTwoCache(){
 SqlSession sqlSession1 = sessionFactory.openSession();
 SqlSession sqlSession2 = sessionFactory.openSession();

 UserMapper userMapper1 = sqlSession1.getMapper(UserMapper. class );
 UserMapper userMapper2 = sqlSession2.getMapper(UserMapper. class );
 //第一次查询,打印了sql语句,并把查询结果放入到缓存中
 User u1 = userMapper1.selectUserByUserId(1);
 System.out.println(u1);
 sqlSession1.close(); //一次查询后关闭SqlSession

 //执行更新操作commit(),会更新二级缓存
 u1.setUsername( "aaa" );
 userMapper3.updateUserByUserId(u1);
 sqlSession3.commit()

 //第二次查询,即使sqlSession已经关闭了,这次查询依然不发出sql语句
 User u2 = userMapper2.selectUserByUserId(1);
 System.out.println(u2);
 sqlSession2.close();
 System.out.println(u1 == u2) //结果为false
 }

??注:二级缓存保存的是查询出来的数据,u2是底层重新生成的User;开启了二级缓存后,还需要将缓存的pojo实现Serializable接口,为了将缓存数据取出来执行反序列化操作,因为二级缓存数据存储介质多种多样,不一定只存在内存中,有可能存在硬盘中,如我们要再取出这个缓存的话,就要反序列化。

4.3.2 useCache和flushCache

??useCache是用来设置二级缓存的,如果设置为false,则表示禁止二级缓存,每次执行这条语句的时候都是从数据库里面查询数据,默认是true
在mapper中,执行了insert和update,delete等操作时需要刷新缓存,不然会出现脏读的情况,flushCache神色中为true时表示这个sql语句要刷新缓存,默认为true

<select id="selectUserByUserId" useCache="false"
  resultType="com.lagou.pojo.User" parameterType="int">
   select * from user where id=#{id}
</select>

原文地址:https://www.cnblogs.com/benjaming0321/p/12546905.html

时间: 2024-11-06 09:33:56

Mybatis(四) Mybatis缓存的相关文章

《深入理解mybatis原理》 MyBatis的一级缓存实现详解 及使用注意事项

0.写在前面 MyBatis是一个简单,小巧但功能非常强大的ORM开源框架,它的功能强大也体现在它的缓存机制上.MyBatis提供了一级缓存.二级缓存 这两个缓存机制,能够很好地处理和维护缓存,以提高系统的性能.本文的目的则是向读者详细介绍MyBatis的一级缓存,深入源码,解析MyBatis一级缓存的实现原理,并且针对一级缓存的特点提出了在实际使用过程中应该注意的事项. 读完本文,你将会学到: 1.什么是一级缓存?为什么使用一级缓存? 2.MyBatis的一级缓存是怎样组织的?(即SqlSes

sping整合redis,以及做mybatis的第三方缓存

一.spring整合redis Redis作为一个时下非常流行的NOSQL语言,不学一下有点过意不去. 背景:学习Redis用到的框架是maven+spring+mybatis(框架如何搭建这边就不叙述了) 首先在pom里面添加当前所需要的jar包,有下面几个: ------ <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <versi

MyBatis Review——查询缓存

一,查询缓存简介 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时候,需要构造sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据.不同的sqlSession之间的缓存数据区域是互相不影响的. 二级缓存是mapper级别的缓存,多个sqlSession去操作同一个mapper的sql语句,多个sqlSession可以共用二级缓存,二级缓存是跨sqlSes

《深入理解mybatis原理6》 MyBatis的一级缓存实现详解 及使用注意事项

<深入理解mybatis原理> MyBatis的一级缓存实现详解 及使用注意事项 0.写在前面   MyBatis是一个简单,小巧但功能非常强大的ORM开源框架,它的功能强大也体现在它的缓存机制上.MyBatis提供了一级缓存.二级缓存 这两个缓存机制,能够很好地处理和维护缓存,以提高系统的性能.本文的目的则是向读者详细介绍MyBatis的一级缓存,深入源码,解析MyBatis一级缓存的实现原理,并且针对一级缓存的特点提出了在实际使用过程中应该注意的事项. 读完本文,你将会学到: 1.什么是一

使用redis作为mybatis的二级缓存

本次介绍一下使用mybatis-redis项目作为mybatis的二级缓存在生产项目中的配置与应用. 首先,在pom中添加一下依赖: <!-- mybatis cache --> <dependency>     <groupId>org.mybatis.caches</groupId>     <artifactId>mybatis-redis</artifactId>     <version>1.0.0-beta2&

mybatis0210 mybatis和ehcache缓存框架整合

1.1mybatis和ehcache缓存框架整合 一般不用mybatis来管理缓存而是用其他缓存框架在管理缓存,因为其他缓存框架管理缓存会更加高效,因为别人专业做缓存的而mybatis专业做sql语句的,mybatis二级缓存通过ehcache维护缓存数据. 1.1.1分布缓存 将缓存数据数据进行分布式管理.用户发起请求,首先会根据负载选择不同的服务器,如果用户在服务器1和服务器2都登录过,那么把用户的session分别放在服务器1和服务器2是不行的,所以就把用户的信息放在远程服务器集群中统一管

mybatis的sql 缓存,去除mybatis缓存

第二次用到mybaits,还是被同一个问题坑了几个小时,所以一定要把这个问题分享给大家.网友很多都是说了一大堆的配置,都是在mybatis.xml中配置.但是,我是没有用mybatis.xml的,我的配置都是在每个**mapper.xml中配置,无非就是一个关联实体类的路径,和一个别名. 在mybatis框架中,在SqlSession未关闭之前,在一个session里面,如果执行相同的select语句,mybatis不会重新查询数据库,而是直接返回缓存在内存中的查询结果,这个是与MyBatis的

MyBatis学习--查询缓存

简介 以前在使用Hibernate的时候知道其有一级缓存和二级缓存,限制ORM框架的发展都是互相吸收其他框架的优点,在Hibernate中也有一级缓存和二级缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存和二级缓存结构如下图: 可以看出一级缓存是sqlSession级别的,而二级缓存是Mapper级别的,同一个Mapper中的多个sqlSession可以共享缓存数据. 一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 sqlSession对象,在对象中有一个数

Mybatis的二级缓存注意点

--声明:一下内容都不一定是正确的,只是自己测试的结果,请自己的动手操作得出自己的结论 1.开启Mybatis的二级缓存,不仅要在SqlMapConfig.xml中进行开启总开关,还要在对应的XXXMapper.xml中开启,缺少其中一个二级缓存都不能开启(起不到二级缓存的作用): 2.开启Mybatis的二级缓存后,一级缓存同样起作用(相同的SqlSession一级缓存,不同的SqlSession二级缓存) 3.一级缓存,只要执行了增删改,不管有没有提交,都会清空缓存,后面如果还有相同sql的