Mybatis入门学习(九、缓存)

缓存

缓存,就是优化数据库性能的一个机制,如果每次发送请求,都要访问数据库,中间的时间以及性能损伤有点大,如果你每次数据都保存在客户端,第二次用的时候,直接获取就很方便了

缓存分类

  • 一级缓存(SQLSession级别)
  • 二级缓存(SQLSessionFactory级别)

下面用示意图解释:


一级缓存:
一级缓存

二级缓存:
在这里插入图片描述

一级缓存

  • 程序默认是使用一级缓存的,但是有以下注意事项:

  • 如果执行增删改的话会刷新缓存,也就是缓存中的数据会不存在

  • 下面通过看代码进一步了解

     		JoinUserDao joinUserDao=sqlSession.getMapper(JoinUserDao.class);
     		User user=joinUserDao.findById(2);
     		System.out.println(user);
     		user=joinUserDao.findById(2);
     		System.out.println(user);
    
  • 这里我执行了两次查询操作,都是查询的ID=2的信息,

  • 那么接下来看控制台信息
    在这里插入图片描述
    控制台只发送了一次sql语句,很明显就是第二次数据就是从我们的缓存中获取的

缓存刷新

那么接下来:我们看看如果提交事务以及增删改会不会刷新

		JoinUserDao joinUserDao=sqlSession.getMapper(JoinUserDao.class);
		User user=joinUserDao.findById(2);
		System.out.println(user);
		sqlSession.commit();
		user=joinUserDao.findById(2);
		System.out.println(user);

这里我们只是单纯的加了一句提交事务,我们看结果
在这里插入图片描述
很明显没有被刷新,那么接下来看我们新增一条数据

		JoinUserDao joinUserDao=sqlSession.getMapper(JoinUserDao.class);
		User user=joinUserDao.findById(2);
		System.out.println(user);
		User user2=new User("800", "qsd", "123");
		joinUserDao.add(user2);
		sqlSession.commit();
		user=joinUserDao.findById(2);
		System.out.println(user);

然后我们看看结果
在这里插入图片描述

部分总结:
  • 很明显看出,程序是默认使用一级缓存的
  • 以及缓存的作用于仅仅是SQLSession,所以如果新创建一个SQLSession,缓存也是不存在的
  • 执行提交事务的时候,不会刷新,但是增删改的时候会刷新

二级缓存

  • 二级缓存需要设置
  • 二级缓存需要关闭一级缓存才能存进去
  • 增删改也会刷新二级缓存
  • 实体类必须要序列化,因为二级缓存一般不是在本地,需要用序列化才能发送数据
二级缓存设置:
<setting name="cacheEnabled" value="true"/>

<!-- 在Mapper文件中设置-->
<cache></cache>
<!-- 实体类实现序列化-->
public class User implements Serializable{}
二级缓存测试
		JoinUserDao joinUserDao=sqlSession.getMapper(JoinUserDao.class);
		User user=joinUserDao.findById(2);
		System.out.println(user);
		
		sqlSession.commit();
		sqlSession.close();
		
		SqlSession sqlSession1=sessionFactory.openSession();
		JoinUserDao joinUserDao1=sqlSession1.getMapper(JoinUserDao.class);
		User user1=joinUserDao1.findById(2);
		System.out.println(user1);
  • 这里先关闭了sqlSession,把一级缓存刷入二级缓存
  • 然而后面从新开启链接,就实现了缓存
  • 下面看结果
    在这里插入图片描述
二级缓存刷新
		JoinUserDao joinUserDao=sqlSession.getMapper(JoinUserDao.class);
		User user=joinUserDao.findById(2);
		System.out.println(user);
		
		User user2=new User("800", "qsd", "123");
		joinUserDao.add(user2);
		sqlSession.commit();
		sqlSession.close();
		
		SqlSession sqlSession1=sessionFactory.openSession();
		JoinUserDao joinUserDao1=sqlSession1.getMapper(JoinUserDao.class);
		User user1=joinUserDao1.findById(2);
		System.out.println(user1);
  • 这里和刚刚一样的,也是加了一个新增属性进去

  • 然后我们看结果
    在这里插入图片描述

  • 这里我们需要注意一下这个测试顺序

     JoinUserDao joinUserDao=sqlSession.getMapper(JoinUserDao.class);
     SqlSession sqlSession1=sessionFactory.openSession();
     JoinUserDao joinUserDao1=sqlSession1.getMapper(JoinUserDao.class);
     User user=joinUserDao.findById(2);
     System.out.println(user);
     
     sqlSession.commit();
     sqlSession.close();
     
     User user2=new User("800", "qsd", "123");
     joinUserDao.add(user2);
     
     User user1=joinUserDao1.findById(2);
     System.out.println(user1);
    
  • 如果你顺序是这样写的话就会出错

  • 因为你都关闭了事务了,新增是加不进去的

关闭缓存刷新

 <insert id="add" parameterType="domain.User" flushCache="false">
		insert into tb_user (id,username,password) values(#{id},#{username},#{password})
</insert>
  • 我们看到了flushCache属性,可以设置为新增的时候不刷新缓存,默认是true(刷新)

  • 下面看下测试代码

      		JoinUserDao joinUserDao=sqlSession.getMapper(JoinUserDao.class);
     		SqlSession sqlSession1=sessionFactory.openSession();
     		JoinUserDao joinUserDao1=sqlSession1.getMapper(JoinUserDao.class);
     		
     		User user=joinUserDao.findById(2);
     		System.out.println(user);
     		
     		User user2=new User("800", "qsd", "123");
     		joinUserDao.add(user2);
     		sqlSession.commit();
     		
     		user=joinUserDao.findById(2);
     		System.out.println(user);
     		sqlSession.close();
     		
     		User user1=joinUserDao1.findById(2);
     		System.out.println(user1);
    
  • 这个代码和之前的一样的,只是我们测试了一级缓存以及二级缓存看是否刷新

  • 下面看结果

在这里插入图片描述
很清楚的看见,缓存都没有被刷新,都被保留下来了

禁用二级缓存

<select id="findById" parameterType="int" resultMap="UserMap" useCache="false">
		select * from tb_user u,tb_banji b where u.id=b.uid and u.username=b.username and u.id=#{id}
</select> 
  • useCache=“false” 这个属性就是禁用二级缓存,但是一级缓存保留

  • 接下来看下测试代码

      		JoinUserDao joinUserDao=sqlSession.getMapper(JoinUserDao.class);
     		SqlSession sqlSession1=sessionFactory.openSession();
     		JoinUserDao joinUserDao1=sqlSession1.getMapper(JoinUserDao.class);
     		
     		User user=joinUserDao.findById(2);
     		System.out.println(user);
     		
     		
     		user=joinUserDao.findById(2);
     		System.out.println(user);
     		sqlSession.close();
     		
     		User user1=joinUserDao1.findById(2);
     		System.out.println(user1);
    
  • 我们来看下结果,就可以知道
    在这里插入图片描述

  • 可以明显看出,禁用的是二级缓存,然而一级缓存还是保留了的

总结

  • 一级缓存是基于SQLSession而二级缓存是基于SQLSEssionFactory
  • 二级缓存在不同的SQLSession可以实现数据共享
  • 查询的结果默认是一级缓存,通过配置可以刷入二级缓存中
  • 配置二级缓存条件如下
    • 启用二级缓存
    • Mapper文件支持
    • 实体类实现序列化
    • 关闭一级缓存
  • 禁用缓存是:userCache
  • 刷新缓存是:flushCache
  • 清空缓存是:sqlSession.clearCache();
  • 缓存的应用场景:
    • 实时性要求不高,更多的是查询业务多
    • 有一定的局限性,一但增删改就会影响数据
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值