“进阶:查询缓存”的版本间差异
跳到导航
跳到搜索
(→示例) |
(→示例) |
||
第119行: | 第119行: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== | === 二级缓存示例 === | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
//获取session1 | //获取session1 |
2020年10月12日 (一) 10:43的版本
关于
Mybatis一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。
Mybatis默认开启一级缓存。
Mybatis二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。
Mybatis二级缓存默认关闭。
一级缓存
- 一级缓存区域是根据SqlSession为单位划分的。
- 每次查询会先从缓存区域找,如果找不到再从数据库查询,并将查询到的数据写入缓存。
- Mybatis内部存储缓存使用一个HashMap。
- key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象;
- sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。
一级缓存示例
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获限mapper接口实例
UserMapper userMapper = session.getMapper(UserMapper.class);
//第一次查询
User user1 = userMapper.findUserById(1);
System.out.println(user1);
//第二次查询,由于是同一个session则不再向数据发出语句直接从缓存取出
User user2 = userMapper.findUserById(1);
System.out.println(user2);
//在同一个session执行更新
User user_update = new User();
user_update.setId(1);
user_update.setUsername("李奎");
userMapper.updateUser(user_update);
session.commit();
//再一次查询,虽然是同一个session但是由于执行了更新操作session的缓存被清空,这里重新发出sql操作
User user3 = userMapper.findUserById(1);
System.out.println(user3);
//关闭session
session.close();
二级缓存
- 二级缓存区域是根据mapper的namespace划分的,相同namespace的mapper查询数据放在同一个区域。
- 如果使用mapper代理方法每个mapper的namespace都不同,此时可以理解为二级缓存区域是根据mapper划分;
- 每次查询会先从缓存区域找,如果找不到再从数据库查询,并将查询到的数据写入缓存。
- Mybatis内部存储缓存使用一个HashMap。
- key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象;
- sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。
开启二级缓存
全局设置
设置 | 描述 | 允许值 | 默认值 |
---|---|---|---|
cacheEnabled | 对在此配置文件下的所有cache 进行全局性开/关设置。 | true | false | true |
Mybatis的二级缓存默认是不开启的,需要时在SqlMapConfig.xml中加入:
<setting name="cacheEnabled" value="true"/>
mapper设置
开启二级缓存不光需要进行全局设置,同时必须在需要的mapper.xml映射文件中启用二级缓存:
<cache type="" />
- type:指定cache接口的实现类的类型
- 指定cache接口的实现类的类型
- Mybatis和ehcache整合,需要配置type为ehcache实现cache接口的类型
如:
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
<!-- 开启本mapper的namespace下的二缓存 -->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
...
实现序列化
二级缓存需要查询结果映射的pojo对象实现java.io.Serializable接口实现序列化和反序列化操作
- 注意如果存在父类、成员pojo都需要实现序列化接口。
public class Orders implements Serializable
public class User implements Serializable
...
如:
public class User implements Serializable {
//属性名和数据库表的字段对应
private int id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
//用户创建的订单列表
private List<Orders> ordersList;
二级缓存示例
//获取session1
SqlSession session1 = sqlSessionFactory.openSession();
UserMapper userMapper = session1.getMapper(UserMapper.class);
//使用session1执行第一次查询
User user1 = userMapper.findUserById(1);
System.out.println(user1);
//关闭session1
session1.close();
//获取session2
SqlSession session2 = sqlSessionFactory.openSession();
UserMapper userMapper2 = session2.getMapper(UserMapper.class);
//使用session2执行第二次查询,由于开启了二级缓存这里从缓存中获取数据不再向数据库发出sql
User user2 = userMapper2.findUserById(1);
System.out.println(user2);
//关闭session2
session2.close();