MyBatis 查询结果的缓存
2020-01-12 16:02:58来源:博客园 阅读 ()
MyBatis 查询结果的缓存
MyBatis的缓存指的是缓存查询结果,当以后使用相同的sql语句、传入相同的参数进行查询时,可直接从mybatis本地缓存中获取查询结果,而不必查询数据库。
mybatis的缓存包括一级缓存、二级缓存,一级缓存默认是开启的,二级缓存默认是关闭的。
一级缓存:
SqlSession级别,在SqlSession中有一个Map,key是由sql语句、参数等信息组成的唯一值,value是查询出来的结果对象。
二级缓存:
mapper级别,同一个namespace下的mapper,有一个Map。
二级缓存可以使这些sqlSession做到查询结果共享。
一级缓存
一级缓存默认是开启的。
User user1 = mapper.queryUserById(1);
User user2 = mapper.queryUserById(1);
第一次查询时,就将查询结果放到一级缓存中。
如果后续使用的sql语句相同、传入的实参也相同,则结果对象也会相同,直接从一级缓存中获取结果对象,不再查询数据库。
User user1 = mapper.queryUserById(1);
sqlSession.commit();
User user2 = mapper.queryUserById(1);
如果此sqlSession调用了commit()方法,会自动清空此sqlSession的一级缓存。
因为使用commit(),会将修改提交到数据库,下一次相同的查询,查询结果可能变了,之前的一级缓存不能再用,所以会自动清空。
User user1 = mapper.queryUserById(1); HashMap<String, Object> map = new HashMap<>(); map.put("username", "张三"); map.put("id", 1); mapper.updateUser(map); User user2 = mapper.queryUserById(1);
事实上,只要此sqlSession调用了<update>、<insert>、<delete>这些会修改数据库的元素,就会清空此sqlSession的一级缓存,不管有没有使用commit()提交。
二级缓存
SqlSession sqlSession1 = MyBatisUtils.getSqlSession(); UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class); User user1 = mapper1.queryUserById(1); System.out.println(user1); SqlSession sqlSession2 = MyBatisUtils.getSqlSession(); UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class); User user2 = mapper2.queryUserById(1); System.out.println(user2);
不使用二级缓存,会执行2次查询。
二级缓存的使用步骤,此处以UserMapper为例:
(1)pojo类要是可序列化的
public class User implements Serializable { //...... }
(2)在mybatis全局配置文件中开启二级缓存
<settings>
<setting name="logImpl" value="LOG4J"/>
<setting name="cacheEnabled" value="true"/>
</settings>
二级缓存默认是关闭的,需要手动开启。
(3)在mapper映射文件中指定二级缓存的实现方式,必须显式指定
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.chy.mapper.UserMapper"> <cache /> <select id="queryUserById" parameterType="integer" resultType="user"> SELECT * FROM user_tb WHERE id=#{id} </select> <update id="updateUser" parameterType="hashmap"> UPDATE user_tb SET username=#{username} WHERE id=#{id} </update> </mapper>
完整写法:
<cache type="perpetualCache" />
type指定二级缓存的实现方式,缺省type时默认使用mybatis自带的perpetualCache。
(4)需要调用close()关闭sqlSession,才会将此sqlSession的查询结果(一级缓存)写入到二级缓存中
SqlSession sqlSession1 = MyBatisUtils.getSqlSession(); UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class); User user1 = mapper1.queryUserById(1); System.out.println(user1); sqlSession1.close(); SqlSession sqlSession2 = MyBatisUtils.getSqlSession(); UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class); User user2 = mapper2.queryUserById(1); System.out.println(user2);
只执行1次查询。后续使用相同sql语句、传入相同的实参进行查询时,直接从二级缓存中获取结果对象。
提交修改时,会清空整个二级缓存:
SqlSession sqlSession1 = MyBatisUtils.getSqlSession(); UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class); User user1 = mapper1.queryUserById(1); System.out.println(user1); HashMap<String, Object> hashMap = new HashMap<>(); hashMap.put("username", "j"); hashMap.put("id", 1); mapper1.updateUser(hashMap); sqlSession1.commit(); SqlSession sqlSession2 = MyBatisUtils.getSqlSession(); UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class); User user2 = mapper2.queryUserById(2); System.out.println(user2);
只写了commit()、实际没有调用<insert> | <update> | <delete>,不会清空二级缓存,反而会将之前查询结果写入到二级缓存。
写了commit()、有调用<insert> | <update> | <delete>,会清空整个二级缓存。
先后调用commit()、close(),不会写入二级缓存,因为commit()的存在,反而会清空整个二级缓存。
原文链接:https://www.cnblogs.com/chy18883701161/p/12158928.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:数的范围(整数二分)
- MyBatis中的$和#,用不好,准备走人! 2020-06-11
- SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 2020-06-11
- 天哪!手动编写mybatis雏形竟然这么简单 2020-06-06
- java实现分页查询 2020-06-05
- MyBatis整合双数据源 2020-06-04
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash