Mybatis----加载策略及注解开发(二)

MyBatis缓存

2.1 为什么使用缓存?

当用户频繁查询某些固定的数据时,第一次将这些数据从数据库中查询出来,保存在缓存中。当用户再

次查询这些数据时,不用再通过数据库查询,而是去缓存里面查询。减少网络连接和数据库查询带来的损

耗,从而提高我们的查询效率,减少高并发访问带来的系统性能问题。

一句话概括:

经常查询一些不经常发生变化的数据,使用缓存来提高查询效率。

 

像大多数的持久化框架一样,Mybatis也提供了缓存策略,通过缓存策略来减少数据库的查询次数,

从而提高性能。 Mybatis中缓存分为一级缓存,二级缓存。

2.2 一级缓存

2.2.1 介绍

一级缓存是SqlSession级别的缓存,是默认开启的

所以在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往

只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时

候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不

会再次发送SQL到数据库。

 

 

4.2.2 验证

 

/*

验证mybatis中的二级缓存

*/

@Test

Public void testTwoCache() throws IOException{

InputStream resourceAsStream=Resources.getResourceAsStream("sqlMapConfig.xml");

SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(resourceAsStream);

SqlSession sqlSession1=sqlSessionFactory.openSession();

UserMapper userMapper=sqlSession1.getMapper(UserMapper.class);

//这是第一次查询

User user1=userMapper.findById(1);

System.out.println(user1);

//只有执行sqlSession.commit或者sqlSession.close,那么一级缓存中的内容才会刷新到二级缓存

sqlSession1.close();

SqlSession sqlSession2=sqlSessionFactory.openSession();

UserMapper userMapper1=sqlSession2.getMapper(UserMapper.class);

User user2=userMapper1.findById(1);

System.out.println(user2);

sqlSession2.close();

}

 

我们可以发现,虽然在上面的代码中我们查询了两次,但最后只执行了一次数据库操作,这就是

Mybatis提供给我们的一级缓存在起作用了。因为一级缓存的存在,导致第二次查询id为1的记录时,并

没有发出sql语句从数据库中查询数据,而是从一级缓存中查询。

 

4.2.3 分析

一级缓存是SqlSession范围的缓存,执行SqlSession的C(增加)U(更新)D(删除)操作,或者调

用clearCache()、commit()、close()方法,都会清空缓存。

 

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

查询用户信息。

2. 得到用户信息,将用户信息存储到一级缓存中。

3. 如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这

样做的目的为了让缓存中存储的是最新的信息,避免脏读。

4. 第二次发起查询用户id为41的用户信息,先去找缓存中是否有id为41的用户信息,缓存中有,直接从缓

存中获取用户信息。

 

4.2.4 清除

<!-- 每次查询时,都会清除缓存 -->

< select flushCache="true"></select>

 

 

//调用sqlSession清除缓存的方法

sqlSession.clearCache();

 

 

2.3 二级缓存

2.3.1 介绍

二级缓存是namspace级别(跨sqlSession)的缓存,是默认不开启的

二级缓存的开启需要进行配置,实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的。

也就是要求实现Serializable接口,配置方法很简单,只需要在映射XML文件配置 <cache/> 就可以开启

二级缓存了。

 

 

2.3.2 验证

a)配置核心配置文件

<settings>

<!--

因为cacheEnabled的取值默认就为true,所以这一步可以省略不配置。

为true代表开启二级缓存;为false代表不开启二级缓存。

-->

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

</settings>

 

b)配置UserMapper.xml映射

<mapper namespace="com.lagou.dao.UserMapper">

<!--当前映射文件开启二级缓存-->

<cache></cache>

<!--

<select>标签中设置useCache=”true”代表当前这个statement要使用二级缓存。

如果不使用二级缓存可以设置为false

注意:

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

-->

<select id="findById" parameterType="int" resultType="user" useCache="true">

 

SELECT * FROM `user` where id = #{id}

</select>

</mapper>

 

c)修改User实体

public class User implements Serializable {

private Integer id;

private String username;

private Date birthday;

private String sex;

private String address;

private List<Role> roleList;

private List<Order> orderList;

}

 

d)测试结果

@Test

public void testTwoCache() throws Exception {

SqlSession sqlSession = MyBatisUtils.openSession();

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

User user = userMapper.findById(41);

System.out.println("第一次查询的用户:" + user);

sqlSession.close();

SqlSession sqlSession1 = MyBatisUtils.openSession();

UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);

User user1 = userMapper1.findById(41);

System.out.println("第二次查询的用户:"+user1);

sqlSession1.close();

}

 

2.3.3 分析

 

二级缓存是mapper映射级别的缓存,多个SqlSession去操作同一个Mapper映射的sql语句,多个

SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

1. 映射语句文件中的所有select语句将会被缓存。

2. 映射语句文件中的所有insert、update和delete语句会刷新缓存。

 

 

2.3.4 注意问题(脏读)

mybatis的二级缓存因为是namespace级别,所以在进行多表查询时会产生脏读问题

 

2.4 小结

 

1. mybatis的缓存,都不需要我们手动存储和获取数据。mybatis自动维护的。

2. mybatis开启了二级缓存后,那么查询顺序:二级缓存--》一级缓存--》数据库

2. 注意:mybatis的二级缓存会存在脏读问题,需要使用第三方的缓存技术解决问题。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Forrest Gump plus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值