当前位置:   article > 正文

【mybatis】 一级缓存&二级缓存_一个service方法 算一个sqlsession吗

一个service方法 算一个sqlsession吗

一级缓存 工作原理图

第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户信息。得到用户信息,将用户信息存储到一级缓存中。

如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。

第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,发现缓存中有,直接从缓存中获取用户信息。

 mybatis默认支持一级缓存,不需要在配置文件去配置。

测试

  1. @Test
  2. public void testCache1() throws Exception{
  3. SqlSession sqlSession = sqlSessionFactory.openSession();//创建代理对象
  4. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  5. //下边查询使用一个SqlSession
  6. //第一次发起请求,查询id为1的用户
  7. User user1 = userMapper.findUserById(1);
  8. System.out.println(user1);
  9. // 如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。
  10. //更新user1的信息
  11. user1.setUsername("测试用户22");
  12. userMapper.updateUser(user1);
  13. //执行commit操作去清空缓存
  14. sqlSession.commit();
  15. //第二次发起请求,查询id为1的用户
  16. User user2 = userMapper.findUserById(1);
  17. System.out.println(user2);
  18. sqlSession.close();
  19. }

一级缓存应用

正式开发,是将mybatis和spring进行整合开发,事务控制在service中。

一个service方法中包括 很多mapper方法调用。

service{

         //开始执行时,开启事务,创建SqlSession对象

         //第一次调用mapper的方法findUserById(1)

         //第二次调用mapper的方法findUserById(1),从一级缓存中取数据

         //方法结束,sqlSession关闭

}

如果是执行两次service调用查询相同 的用户信息,不走一级缓存,因为session方法结束,sqlSession就关闭,一级缓存就清空。

 二级缓存

1、开启二级缓存

mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓存。

在核心配置文件SqlMapConfig.xml中加入

<setting name="cacheEnabled" value="true"/>

 

描述

允许值

默认值

cacheEnabled

对在此配置文件下的所有cache 进行全局性开/关设置。

true false

true

 

在UserMapper.xml中开启二缓存,UserMapper.xml下的sql执行完成会存储到它的缓存区域(HashMap)。

 

2、调用pojo类实现序列化接口

为了将缓存数据取出执行反序列化操作

因为二级缓存数据存储介质多种多样,不一样在内存,有可能存在硬盘上,从硬盘取出需要反序列化。

 

3、测试方法

  1. // 二级缓存测试
  2.    @Test
  3.    public void testCache2() throws Exception {
  4.       SqlSession sqlSession1 = sqlSessionFactory.openSession();
  5.       SqlSession sqlSession2 = sqlSessionFactory.openSession();
  6.       SqlSession sqlSession3 = sqlSessionFactory.openSession();
  7.       // 创建代理对象
  8.       UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
  9.       // 第一次发起请求,查询id为1的用户
  10.       User user1 = userMapper1.findUserById(1);
  11.       System.out.println(user1);
  12.       //这里执行关闭操作,将sqlsession中的数据写到二级缓存区域
  13.       sqlSession1.close();
  14.       //使用sqlSession3执行commit()操作
  15.       UserMapper userMapper3 = sqlSession3.getMapper(UserMapper.class);
  16.       User user  = userMapper3.findUserById(1);
  17.       user.setUsername("张明明");
  18.       userMapper3.updateUser(user);
  19.       //执行提交,清空UserMapper下边的二级缓存
  20.       sqlSession3.commit();
  21.       sqlSession3.close();
  22.       UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
  23.       // 第二次发起请求,查询id为1的用户
  24.       User user2 = userMapper2.findUserById(1);
  25.       System.out.println(user2);
  26.       sqlSession2.close();
  27.    }

 

useCache配置---statement二级缓存开关

在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。

<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">

总结:针对每次查询都需要最新的数据sql,要设置成useCache=false,禁用二级缓存。

 

刷新缓存(就是清空缓存)

在mapper的同一个namespace中,如果有其它insert、update、delete操作数据后需要刷新缓存,如果不执行刷新缓存会出现脏读。

 设置statement配置中的flushCache="true" 属性,默认情况下为true即刷新缓存,如果改成false则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读。

如下:

<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">

总结:一般下执行完commit操作都需要刷新缓存,flushCache=true表示刷新缓存,这样可以避免数据库脏读。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/159880?site
推荐阅读
相关标签
  

闽ICP备14008679号