对于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>

总结

最新文章

  1. ABP(现代ASP.NET样板开发框架)系列之16、ABP应用层——数据传输对象(DTOs)
  2. Android线程管理之ExecutorService线程池
  3. centos7 添加svn
  4. Android N preview 试用
  5. Python基础之:List
  6. &lt;%# Convert.ToDecimal(Eval(&quot;IMLognum&quot;)).ToString(&quot;F0&quot;) %&gt;
  7. MySQL--INFORMATION_SCHEMA COLUMNS表
  8. 6个好用的Web开发工具
  9. debian 学习记录-2 -账户 -关机
  10. 评测:VPS推荐digitalocean和Vultr和Linode
  11. [BZOJ1002] [FJOI2007] 轮状病毒 (数学)
  12. return ||和return &amp;&amp; 区别
  13. Mysql半同步复制模式说明及配置示例 - 运维小结
  14. memcache的下载与安装
  15. 一个有趣的小例子,带你入门协程模块-asyncio
  16. 【Python55--爬虫:代理】
  17. Webscoket
  18. hbase源码系列(九)StoreFile存储格式
  19. java与Excel (.xls文件) ---使用JXL创建,增添表格文件
  20. angularjs获取元素以及angular.element()用法

热门文章

  1. 一篇文章讲透Dijkstra最短路径算法
  2. leetcode976之三角形最大周长
  3. Java实现 LeetCode 697 数组的度(类似于数组的map)
  4. Java实现 LeetCode 316 去除重复字母
  5. NumPy之计算两个矩阵的成对平方欧氏距离
  6. Alink漫谈(六) : TF-IDF算法的实现
  7. BitMap算法及其实现(Python)
  8. Windows下虚拟机Linux(CentOS8)扩容设置 - 磁盘扩容中的坑和解决方法
  9. 什么?你还不会身份证号码验证?最全的身份证正则验证js
  10. java Exception 处理汇总