对于mybatis框架。仿佛工作中一直是在copy着使用。对于mybatis缓存。并没有一个准确的认知。趁着假期。学习下mybatis的缓存。这篇主要学习mybatis的一级缓存。

为什么使用缓存

其实,大家工作久了,就知道很多瓶颈就是在数据库上。

初识mybatis一级缓存

当然我们还是通过代码来认识下mybatis的一级缓存

代码演示

详细代码见github,这里只展示重要的代码片段

  1. tempMapper.xml
    <select id="getById" resultType="entity.TempEntity">
select * from temp where id = #{id}
</select>
  1. TempTest
public class TempTest {

    Logger logger = Logger.getLogger(this.getClass());
@Test
public void test() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = build.openSession();
TempEntity tempEntity1 = sqlSession.selectOne("dao.TempDao.getById", 1);
logger.info(tempEntity1);
TempEntity tempEntity2 = sqlSession.selectOne("dao.TempDao.getById", 1);
logger.info(tempEntity2);
logger.info(tempEntity1 == tempEntity2);
}
}

3.运行结果

2020-06-26 08:57:37,453 DEBUG [dao.TempDao.getById] - ==>  Preparing: select * from temp where id = ?
2020-06-26 08:57:37,513 DEBUG [dao.TempDao.getById] - ==> Parameters: 1(Integer)
2020-06-26 08:57:37,538 DEBUG [dao.TempDao.getById] - <== Total: 1
2020-06-26 08:57:37,538 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}
2020-06-26 08:57:37,538 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}
2020-06-26 08:57:37,538 INFO [TempTest] - true
  1. 总结

4.1 从上面的结果,我们可以看到,第二次查询的时候,就直接没有查询数据库,并且返回的是同一个对象。证明第二次走的就是缓存。

4.2 一级缓存是默认开启的。我们并没有在代码中配置任何关于缓存的配置

4.3 代码回顾

mybatis一级缓存命中原则

mybatis是怎么样判断某两次查询是完全相同的查询?

1.statementId

1.1 mapper.xml

    <select id="getById1" resultType="entity.TempEntity">
select * from temp where id = #{id}
</select> <select id="getById2" resultType="entity.TempEntity">
select * from temp where id = #{id}
</select>

1.2 test

    @Test
public void test() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = build.openSession();
TempEntity tempEntity1 = sqlSession.selectOne("dao.Temp2Dao.getById1", 1);
logger.info(tempEntity1);
TempEntity tempEntity2 = sqlSession.selectOne("dao.Temp2Dao.getById2", 1);
logger.info(tempEntity2);
logger.info(tempEntity1 == tempEntity2);
}

1.3 结果

2020-06-26 09:19:09,926 DEBUG [dao.Temp2Dao.getById1] - ==>  Preparing: select * from temp where id = ?
2020-06-26 09:19:09,957 DEBUG [dao.Temp2Dao.getById1] - ==> Parameters: 1(Integer)
2020-06-26 09:19:09,969 DEBUG [dao.Temp2Dao.getById1] - <== Total: 1
2020-06-26 09:19:09,969 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}
2020-06-26 09:19:09,969 DEBUG [dao.Temp2Dao.getById2] - ==> Preparing: select * from temp where id = ?
2020-06-26 09:19:09,970 DEBUG [dao.Temp2Dao.getById2] - ==> Parameters: 1(Integer)
2020-06-26 09:19:09,970 DEBUG [dao.Temp2Dao.getById2] - <== Total: 1
2020-06-26 09:19:09,971 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}

1.4 总结

要求查询的statementId必须完全相同,否则无法命中缓存,即时两个查询语句、参数完全相同

2.查询参数

我们用不同的参数查询,一个传1 一个传2

2.1 test

    @Test
public void testParam() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = build.openSession();
TempEntity tempEntity1 = sqlSession.selectOne("dao.Temp2Dao.getById1", 1);
logger.info(tempEntity1);
TempEntity tempEntity2 = sqlSession.selectOne("dao.Temp2Dao.getById1", 2);
logger.info(tempEntity2);
logger.info(tempEntity1 == tempEntity2);
}

2.2 结果

2020-06-26 09:24:33,107 DEBUG [dao.Temp2Dao.getById1] - ==>  Preparing: select * from temp where id = ?
2020-06-26 09:24:33,148 DEBUG [dao.Temp2Dao.getById1] - ==> Parameters: 1(Integer)
2020-06-26 09:24:33,162 DEBUG [dao.Temp2Dao.getById1] - <== Total: 1
2020-06-26 09:24:33,162 INFO [TempTest] - TempEntity{id=1, value1='11111', value2='aaaaa'}
2020-06-26 09:24:33,162 DEBUG [dao.Temp2Dao.getById1] - ==> Preparing: select * from temp where id = ?
2020-06-26 09:24:33,163 DEBUG [dao.Temp2Dao.getById1] - ==> Parameters: 2(Integer)
2020-06-26 09:24:33,164 DEBUG [dao.Temp2Dao.getById1] - <== Total: 1
2020-06-26 09:24:33,164 INFO [TempTest] - TempEntity{id=2, value1='22222', value2='bbbb'}
2020-06-26 09:24:33,164 INFO [TempTest] - false

2.3 总结

要求传递给sql的传递参数相同,否则不会命中缓存

3.分页参数

3.1 传不同的分页参数

    @Test
public void testPage() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = build.openSession();
RowBounds rowBounds1 = new RowBounds(0,1);
List<TempEntity> tempEntity1 = sqlSession.selectList("dao.Temp2Dao.getList", null,rowBounds1);
logger.info(tempEntity1);
RowBounds rowBounds2 = new RowBounds(0,2);
List<TempEntity> tempEntity2 = sqlSession.selectList("dao.Temp2Dao.getList",null, rowBounds2);
logger.info(tempEntity2);
logger.info(tempEntity1 == tempEntity2);
}

3.2 结果

2020-06-26 10:10:33,060 DEBUG [dao.Temp2Dao.getList] - ==>  Preparing: select * from temp where 1=1
2020-06-26 10:10:33,101 DEBUG [dao.Temp2Dao.getList] - ==> Parameters:
2020-06-26 10:10:33,116 INFO [TempTest] - [TempEntity{id=1, value1='11111', value2='aaaaa'}]
2020-06-26 10:10:33,116 DEBUG [dao.Temp2Dao.getList] - ==> Preparing: select * from temp where 1=1
2020-06-26 10:10:33,116 DEBUG [dao.Temp2Dao.getList] - ==> Parameters:
2020-06-26 10:10:33,118 INFO [TempTest] - [TempEntity{id=1, value1='11111', value2='aaaaa'}, TempEntity{id=2, value1='22222', value2='bbbb'}]
2020-06-26 10:10:33,118 INFO [TempTest] - false

3.3 总结

要求分页参数必须相同,否则无法命中缓存。缓存的粒度是整个分页查询结果,而不是结果中的每个对象

4. sql语句

4.1 mapper文件

    <select id="getById" resultType="entity.TempEntity">
select * from temp
<where>
<if test="type ==1">
id = #{id}
</if>
<if test="type ==2">
1=1 and id = #{id}
</if>
</where>
</select>

这个就不测试了。

4.2 总结

要求传递给jdbc的sql 必须完全相同。就算是1=1 不起作用 也不行

5.环境

这里的环境指的的是<environment id="dev"><environment id="test"> 也是会影响的

    <environments default="dev">
<environment id="dev">
<!--指定事务管理的类型,这里简单使用Java的JDBC的提交和回滚设置-->
<transactionManager type="JDBC"></transactionManager>
<!--dataSource 指连接源配置,POOLED是JDBC连接对象的数据源连接池的实现-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</dataSource>
</environment>
<environment id="test">
<!--指定事务管理的类型,这里简单使用Java的JDBC的提交和回滚设置-->
<transactionManager type="JDBC"></transactionManager>
<!--dataSource 指连接源配置,POOLED是JDBC连接对象的数据源连接池的实现-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</dataSource>
</environment>
</environments>

总结

mybatis缓存之一级缓存(一)的更多相关文章

  1. MyBatis 延迟加载,一级缓存,二级缓存设置

    什么是延迟加载 resultMap中的association和collection标签具有延迟加载的功能. 延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息.使用关联信息时再去加载关联信息 ...

  2. 八 mybatis查询缓存(一级缓存,二级缓存)和ehcache整合

    1       查询缓存 1.1     什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存.

  3. mybatis由浅入深day02_7查询缓存_7.2一级缓存_一级缓存应用

    7 查询缓存 7.1 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时 ...

  4. 【MyBatis学习12】MyBatis中的一级缓存

    缓存的作用是减轻数据库的压力,提高数据库的性能的.mybatis中提供了一级缓存和二级缓存,先来看一下两个缓存的示意图:   从图中可以看出: 一级缓存是SqlSession级别的缓存.在操作数据库时 ...

  5. Mybatis延迟加载, 一级缓存、二级缓存

    延迟加载 概念:MyBatis中的延迟加载,也称为懒加载,是指在进行关联查询时,按照设置延迟规则推迟对关联对象的select查询.延迟加载可以有效的减少数据库压力. (注意:MyBatis的延迟加载只 ...

  6. 阶段3 1.Mybatis_11.Mybatis的缓存_6 Mybatis中的一级缓存

    Mybatis中的一级缓存和二级缓存         一级缓存:             它指的是Mybatis中SqlSession对象的缓存.             当我们执行查询之后,查询的结 ...

  7. MyBatis之一级缓存及其一级缓存失效

    定义: 一级缓存:本地缓存:与数据库同一次会话(sqlSession)期间查询到的数据会放在本地缓存中,如果以后要获取相同的数据直接从缓存中获取,不会再次向数据库查询数据一个SqlSession拥有一 ...

  8. Mybatis进阶使用-一级缓存与二级缓存

    简介 缓存是一般的ORM 框架都会提供的功能,目的就是提升查询的效率和减少数据库的压力.跟Hibernate 一样,MyBatis 也有一级缓存和二级缓存,并且预留了集成第三方缓存的接口. 一级缓存 ...

  9. MyBatis加强(1)~缓存机制(一级缓存、二级缓存、第三方缓存技术redis、ehcache)

    一.缓存机制 使用缓存可以使应用更快地获取数据,避免频繁的数据库交互操作,尤其是在查询越多,缓存命中率越高 的情况下,缓存的作用就越明显. 1.缓存原理:Map ■ 查询时,先从缓存区查询:找到,返回 ...

  10. 【转】hibernate缓存:一级缓存和二级缓存

    什么是缓存? 缓存是介于物理数据源与应用程序之间,是对数据库中的数据复制一份临时放在内存中的容器,其作用是为了减少应用程序对物理数据源访问的次数,从而提高了应用程序的运行性能.Hibernate在进行 ...

随机推荐

  1. 01 . 分布式存储之FastDFS简介及部署

    分布式存储简介 现代的互联网已经进入大数据时代,每天都有数以万计的数据产生,这些数据的规模轻轻松松地可以达到几P的级别,传统的的单机存储早已捉襟见肘,根本无法满足大数据对存储系统的要求.这时,各种分布 ...

  2. 运用惰性删除和定时删除实现可过期的localStorage缓存

    localStorage简介 使用localStorage可以在浏览器中存储键值对的数据.经常被和localStorage一并提及的是sessionStorage,它们都可以在当浏览器中存储键值对的数 ...

  3. Shell脚本 (二) 变量与运算符

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 四.Shell 中的变量 1.系统变量 1.1 常用系统变量 $HOME. $PWD. $SHELL . ...

  4. Java实现 LeetCode 725 分隔链表(暴力)

    725. 分隔链表 给定一个头结点为 root 的链表, 编写一个函数以将链表分隔为 k 个连续的部分. 每部分的长度应该尽可能的相等: 任意两部分的长度差距不能超过 1,也就是说可能有些部分为 nu ...

  5. Java实现十六进制转十进制

    基础练习 十六进制转十进制 时间限制:1.0s 内存限制:512.0MB 提交此题 锦囊1 锦囊2 问题描述 从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出. 注:十六进 ...

  6. Java实现第十届蓝桥杯JavaC组第十题(试题J)扫地机器人

    扫地机器人 时间限制: 1.0s 内存限制: 512.0MB 本题总分:25 分 [问题描述] 小明公司的办公区有一条长长的走廊,由 N 个方格区域组成,如下图所 示. 走廊内部署了 K 台扫地机器人 ...

  7. Java实现第八届蓝桥杯正则问题

    正则问题 考虑一种简单的正则表达式: 只由 x ( ) | 组成的正则表达式. 小明想求出这个正则表达式能接受的最长字符串的长度. 例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是 ...

  8. java实现第九届蓝桥杯版本分支

    版本分支 第五题:版本分支 小明负责维护公司一个奇怪的项目.这个项目的代码一直在不断分支(branch)但是从未发生过合并(merge). 现在这个项目的代码一共有N个版本,编号1~N,其中1号版本是 ...

  9. 深入剖析AQS

    目录 摘要 AbstractQueuedSynchronizer实现一把锁 ReentrantLock ReentrantLock的特点 Synchronized的基础用法 ReentrantLock ...

  10. 聊一聊Asp.net过滤器Filter那一些事

    最近在整理优化.net代码时,发现几个很不友好的处理现象:登录判断.权限认证.日志记录.异常处理等通用操作,在项目中的action中到处都是.在代码优化上,这一点是很重要着力点.这是.net中的过滤器 ...