查看“进阶:查询缓存”的源代码
←
进阶:查询缓存
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[category:Mybatis]] __TOC__ == 关于 == [[File:Mybatis缓存.png|800px]] Mybatis一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。<br/> Mybatis默认开启一级缓存。 <br/><br/> Mybatis二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。<br/> Mybatis二级缓存默认关闭。 == 一级缓存 == [[File:Mybatis一级缓存.png|500px]] # 一级缓存区域是根据SqlSession为单位划分的。 # 每次查询会先从缓存区域找,如果找不到再从数据库查询,并将查询到的数据写入缓存。 # Mybatis内部存储缓存使用一个'''HashMap'''。 #* key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象; # sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。 === 示例 === <syntaxhighlight lang="java"> @Test public void testCache1() throws Exception{ SqlSession sqlSession = sqlSessionFactory.openSession();//创建代理对象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //以下查询使用一个SqlSession //第一次发起请求,查询id为1的用户 User user1 = userMapper.findUserById(1); System.out.println(user1); //第二次发起请求,查询id为1的用户 //与user1执行的是相同sql,可以使用一级缓存 User user2 = userMapper.findUserById(1); System.out.println(user2); //在同一个session执行更新 //执行commit操作,清空一级缓存,避免脏读。 User user_update = new User(); user_update.setId(1); user_update.setUsername("李奎"); userMapper.updateUser(user_update); session.commit(); //再次发起请求,查询id为1的用户 //缓存无相应内容,需要查询数据库 User user3 = userMapper.findUserById(1); System.out.println(user3); //关闭sqlSession sqlSession.close(); } </syntaxhighlight> == 二级缓存 == [[File:Mybatis二级缓存.png|500px]] # '''二级缓存区域是根据mapper的namespace划分的,相同namespace的mapper查询数据放在同一个区域'''。 #* 如果使用mapper代理方法每个mapper的namespace都不同,此时可以理解为二级缓存区域是根据mapper划分; # 每次查询会先从缓存区域找,如果找不到再从数据库查询,并将查询到的数据写入缓存。 # Mybatis内部存储缓存使用一个'''HashMap'''。 #* key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象; # sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。 === 设置 === ==== SqlMapConfig.xml ==== {| class="wikitable" ! 设置 !! 描述 !! 允许值 !! 默认值 |- | cacheEnabled | 对在此配置文件下的所有cache 进行全局性开/关设置。 | <nowiki>true | false</nowiki> | true |} Mybatis的二级缓存默认是不开启的,需要时在SqlMapConfig.xml中加入: <syntaxhighlight lang="xml"> <setting name="cacheEnabled" value="true"/> </syntaxhighlight> ==== Mapper.xml ==== 开启二级缓存不光需要进行全局设置,'''同时必须在需要的mapper.xml映射文件中启用二级缓存''': <syntaxhighlight lang="xml"> <cache /> </syntaxhighlight> <syntaxhighlight lang="xml"> <cache type="" /> </syntaxhighlight> * '''type''':指定cache接口的实现类的类型 *# 指定cache接口的实现类的类型 *# Mybatis和ehcache整合,需要配置type为ehcache实现cache接口的类型 如: <syntaxhighlight lang="xml"> <mapper namespace="cn.itcast.mybatis.mapper.UserMapper"> <!-- 开启本mapper的namespace下的二缓存 --> <cache type="org.mybatis.caches.ehcache.EhcacheCache"/> ... </syntaxhighlight> ===== Cache参数 ===== {| class="wikitable" ! 设置 !! 描述 !! 允许值 !! 默认值 |- | flushInterval | 缓存刷新间隔(单位毫秒)。 * 默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。 | 任意正整数 | Not set |- | size | 设置缓存结果对象或列表的引用大小。 | 任意正整数 | 1024 |- | readOnly | 设置缓存只读。只读缓存会给所有调用者返回缓存对象的相同实例,因此这些对象不能被修改。 # 在不同线程中的调用者之间修改它们会导致冲突; # 可读写的缓存会返回缓存对象的拷贝(通过序列化),慢,安全(因此该属性默认false); | <nowiki>true | false</nowiki> | false |- | eviction | 缓存收回策略。 | # LRU:最近最少使用的策略,移除最长时间不被使用的对象 # FIFO:先进先出测试,按对象进行缓存的顺序来移除他们 # SOFT:软引用策略,移除基于垃圾回收器状态和软引用规则的对象 # WEAK:弱引用策略,更积极的移除基于垃圾收集器状态和弱引用规则的对象 | LRU |} 如: <syntaxhighlight lang="xml"> <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/> </syntaxhighlight> : 使用了一个“以FIFO进行回收,并每隔 60 秒刷新,缓存Hashmap有512个引用,而且返回只读对象”的二级缓存。 ==== statement ==== ===== 禁用缓存 ===== 在statement中设置useCache=false可以禁用当前statement(即当前select语句)的二级缓存,即每次查询都会发出sql去查询。 # 默认情况是true,即该sql使用二级缓存; # 针对每次查询都需要最新的数据sql,要设置成useCache=false,禁用二级缓存; 如: <syntaxhighlight lang="xml"> <select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false"> </syntaxhighlight> ===== 刷新缓存 ===== 在mapper的同一个namespace中,如果有其它insert、update、delete操作数据后需要刷新缓存,如果不执行刷新缓存会出现脏读。 # 默认情况下为true(即刷新缓存),如果改成false则不会刷新。 # 一般下执行完commit操作都需要刷新缓存,以避免数据库脏读。 # (使用缓存时,如果手动修改数据库表中的查询数据会出现脏读)。 如: <syntaxhighlight lang="xml"> <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true"> </syntaxhighlight> ==== po ==== 二级缓存需要'''查询结果映射的pojo对象实现java.io.Serializable接口实现序列化和反序列化操作''' * 注意如果存在父类、成员pojo都需要实现序列化接口。 <syntaxhighlight lang="java"> public class Orders implements Serializable public class User implements Serializable ... </syntaxhighlight> 如: <syntaxhighlight lang="java" highlight="1"> public class User implements Serializable { //属性名和数据库表的字段对应 private int id; private String username;// 用户姓名 private String sex;// 性别 private Date birthday;// 生日 private String address;// 地址 //用户创建的订单列表 private List<Orders> ordersList; </syntaxhighlight> === 示例 === <syntaxhighlight lang="java"> @Test public void testCache2() throws Exception { SqlSession sqlSession1 = sqlSessionFactory.openSession(); SqlSession sqlSession2 = sqlSessionFactory.openSession(); SqlSession sqlSession3 = sqlSessionFactory.openSession(); SqlSession sqlSession4 = sqlSessionFactory.openSession(); // 创建代理对象 UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class); // 第一次发起请求,查询id为1的用户 User user1 = userMapper1.findUserById(1); System.out.println(user1); //这里执行关闭操作,将sqlsession中的数据写到二级缓存区域 sqlSession1.close(); UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class); // 第二次发起请求,查询id为1的用户 // 与sqlSession2请求相同,读取二级缓存,而不查询数据库 User user2 = userMapper2.findUserById(1); System.out.println(user2); //这里关闭操作,并将sqlsession中的数据写到二级缓存区域 sqlSession2.close(); //使用sqlSession3执行commit()操作 UserMapper userMapper3 = sqlSession3.getMapper(UserMapper.class); User user = userMapper3.findUserById(1); user.setUsername("张明明"); userMapper3.updateUser(user); //执行提交,清空UserMapper下边的二级缓存 sqlSession3.commit(); sqlSession3.close(); UserMapper userMapper4 = sqlSession4.getMapper(UserMapper.class); // 再一次发起请求,查询id为1的用户, // 由于commit操作导致缓存被清空,这里重新发出sql操作 User user4 = userMapper4.findUserById(1); System.out.println(user4); //这里关闭操作,并将sqlsession中的数据写到二级缓存区域 sqlSession4.close(); } </syntaxhighlight> == 整合ehcache ==
返回至“
进阶:查询缓存
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息