关于mybatis基础我们前面几篇博客已经介绍了很多了,今天我们来说一个简单的问题,那就是mybatis中的缓存问题。mybatis本身对缓存提供了支持,但是如果我们没有进行任何配置,那么默认情况下系统只开启了一级缓存,一级缓存就是同一个SqlSession执行的相同查询是会进行缓存的,OK,那么今天我们就来看看这些缓存,并简单验证下。

系统默认开启了一级缓存

这个缓存系统默认情况下是开启的,当我们获取到一个SqlSession对象之后,如果调用SqlSession中的同一个方法查询同一条数据,那么第二次查询将不会去数据库中查询,因为第一次查询有缓存,直接调用缓存数据即可,除非缓存超时或者我们明确声明数据要刷新,否则都是直接调用缓存数据。OK,我们来看一个简单的案例。
查询代码如下:

SqlSession sqlSession = null;
try {
sqlSession = DBUtils.openSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//查询同一条数据时会缓存
User user = mapper.getUser(1l);
User user2 = mapper.getUser(1l);
System.out.println(user.toString());
System.out.println(user2.toString());
sqlSession.commit();
} catch (Exception e) {
System.err.println(e.getMessage());
sqlSession.rollback();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}

我们来看看日志:

小伙伴们看到,我这里执行了两次查询,但实际上只执行了一次SQL语句。

自己配置二级缓存

上面的缓存是由系统默认配置的,这个有一定的局限性,就是只能在同一个SqlSession中有效,脱离了同一个SqlSession就没法使用这个缓存了,有的时候我们可能希望能够跨SqlSession进行数据缓存。那么这个时候需要我们进行手动开启二级缓存。
二级缓存的开启方式其实很简单,只需要我们在userMapper.xml中配置<cache/>节点即可。如下:

<?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="org.sang.db.UserMapper">
<cache/>
<select id="getUser" resultType="org.sang.bean.User" parameterType="Long">
select * from user where id = #{id}
</select>
<insert id="insertUser" parameterType="org.sang.bean.User">
INSERT INTO user(username,password,address) VALUES (#{username},#{password},#{address})
</insert>
<delete id="deleteUser" parameterType="Long">
DELETE FROM user where id=#{id}
</delete>
<select id="getAll" resultType="u">
SELECT * from user
</select>
</mapper>

这样简单配置之后,二级缓存就算开启了,这样的配置中,许多东西都是默认的,比如所有的select语句都会被缓存,所有的delete、insert和update则都会将缓存刷新,还比如缓存将使用LRU算法进行内存回收等。那么这些东西如果需要配置的话,我们可以按如下方式进行配置:
<cache eviction="LRU" flushInterval="20000" size="1024" readOnly="true"/>,这里的eviction表示缓存策略,除了LRU之外还有先进先出(FIFO)、软引用(SOFT)、弱引用(WEAK)等,flushInterval则表示刷新时间,表示缓存的对象个数,readOnly为true则表示缓存只可以读取不可以修改。
OK,做了如上配置之后还不够,开启二级缓存还要求我们的实体类可以序列化,实现Serializable接口即可,如下:

public class User implements Serializable{
private Long id;
private String username;
private String password;
private String address; ... }

如此之后,我们的二级缓存就算成功开启了,OK,我么来测试下:

SqlSession sqlSession = null;
SqlSession sqlSession2 = null;
try {
sqlSession = DBUtils.openSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUser(1l);
System.out.println(user.toString());
sqlSession.commit();
sqlSession2 = DBUtils.openSqlSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.getUser(1l);
System.out.println(user2.toString());
sqlSession2.commit();
} catch (Exception e) {
System.err.println(e.getMessage());
sqlSession.rollback();
sqlSession2.rollback();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
if (sqlSession2 != null) {
sqlSession2.close();
}
}

打印日志如下:

OK,小伙伴们看到SQL语句实际上只执行了一次。

OK,以上就是对mybatis中缓存的一个简单介绍。

本文案例下载:
本文案例GitHub地址https://github.com/lenve/JavaEETest/tree/master/Test27-mybatis8

参考资料:
《深入浅出MyBatis 技术原理与实战》

关注公众号【江南一点雨】,专注于 Spring Boot+微服务以及前后端分离等全栈技术,定期视频教程分享,关注后回复 Java ,领取松哥为你精心准备的 Java 干货!

mybatis中的缓存问题的更多相关文章

  1. [原创]关于mybatis中一级缓存和二级缓存的简单介绍

    关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...

  2. SSM-MyBatis-17:Mybatis中一级缓存(主要是一级缓存存在性的证明,增删改对一级缓存会造成什么影响)

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 缓存------------------------------------------> 很熟悉的一个 ...

  3. 关于mybatis中一级缓存和二级缓存的简单介绍

    关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...

  4. Mybatis中的缓存管理

    目录 Mybatis中的缓存管理 查询缓存工作原理: 配置缓存: 默认配置: 使用二级缓存: 刷新缓存过程: 配置EHcache 产生脏数据 使用原则: Mybatis中的缓存管理 查询缓存工作原理: ...

  5. SSM-MyBatis-18:Mybatis中二级缓存和第三方Ehcache配置

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 二级缓存 Mybatis中,默认二级缓存是开启的.可以关闭. 一级缓存开启的.可以被卸载吗?不可以的.一级缓存 ...

  6. MyBatis中的缓存1

    1.应用程序和数据库交互的过程是一个相对比较耗时的过程 2.缓存存在的意义:让应用程序减少对数据库的访问,提升程序运行的xiaolv 3.MyBatis中默认SqlSession缓存开启 3.1  同 ...

  7. Mybatis中的缓存

    Mybatis提供缓存查询功能,用于减轻数据库压力,提升数据查询能力. Mybatis中定义了两级缓存:包括一级缓存与二级缓存.示意图如下所示: 一.一级缓存 一级缓存的特点: 每一个SqlSessi ...

  8. MyBatis中二级缓存和延时加载同时开启的问题

    首先,二级缓存默认不开启! 要配置 <setting name="cacheEnabled" value="true"/> 在MyBatis中:一级 ...

  9. 一次读懂mybatis中的缓存机制

    缓存功能针对于查询(没听说果UPDATE,INSERT语句要缓存什么,都是直接执行的) 默认情况下,mybatis会启用一级缓存. 如果使用同一个session对象调用了相同的SELECT语句,则直接 ...

随机推荐

  1. JAVA递归生成树形菜单

    递归生成一个如图的菜单,编写两个类数据模型Menu.和创建树形的MenuTree.通过以下过程实现: 1.首先从菜单数据中获取所有根节点. 2.为根节点建立次级子树并拼接上. 3.递归为子节点建立次级 ...

  2. arp断网攻击

    arp断网攻击可以是同局域网内主机无法上网!(可恶搞室友哦,嘻嘻!) 实现原理 arp的中文释义是地址解析协议,全英文 address resolution protocol,是一个将局域网IP地址映 ...

  3. centos7 安装 oh my zsh

    和在ubuntu 下安装十分相似(基本没区别) 安装zsh yum install zsh 改变系统bash chsh -s /bin/zsh git clone oh my zsh 项目: git@ ...

  4. vue中使用stylus

    1.创建完成一个初始项目后,通过 npm install stylus -D命令,在项目内安装stylus.(注意:命令结尾 -D 即是 --save-dev 的简写形式) 2.需要安装loader, ...

  5. Hive表生成函数explode讲解

    Hive中的表分析函数接受零个或多个输入,然后产生多列或多行输出. 1.explode函数 explode函数以array类型数据输入,然后对数组中的数据进行迭代,返回多行结果,一行一个数组元素值 A ...

  6. KMP性质小结

    跪拜_Blackjack_神犇

  7. 软件工程第三周的学习报告 html<input> final finally finalize 的比较 BigInteger

    三月十三号下午: html的<input>的三个属性pattern(限定用户的输入格式)与placeholder(显示的)与required(不能为空) 代码案例: pattern与pla ...

  8. linux configure 应用

    linux下configure命令详细介绍 2018年01月11日 15:02:20 冷月霜 阅读数:705 标签: configure 更多 个人分类: 数据库技术   Linux环境下的软件安装, ...

  9. dedecms给图片加水印覆盖整张图片

    位置: /include/image.class.php $wmwidth = $imagewidth - $logowidth; $wmheight = $imageheight - $logohe ...

  10. node-basis(提供nodejs开发的基础包)

    地址: https://github.com/flybirdsoft/use-node-basis