mybati缓存机制之一级缓存

  在月黑风高的某天夜晚,boss chen语重心长的发条了消息给小草说:“小草啊,是时候写写博客来记录平常自己积累的东西了......”。小草一听,平常没有写博客的习惯,在平常开发中只是用笔记记录自己的所得(分散的小点),写博客的心思还处于萌芽之中,boss chen的话彻底让萌芽“破土而出”。

之后便有了本博主的博客之旅......小草的Dream。

  第一次写博客,也不知道从哪里开始写,想来想去先从平常接触比较多的mybatis开始写吧!

mybatis的缓存机制

一级缓存

mybatis配置中是默认启用一级缓存的(默认的是SESSION级别),当然也可以再次手动设置

<setting name="localCacheScope" value="SESSION"/>

 注:一级缓存有连个选项,SESSION或者STATEMENT,默认是SESSION。

测试案例:

  1.在一个service中对某个id查询多次

  可以看出真正与数据库交互的只有第一次查询,第二次,第三次查询是通过查询缓存得出的。

  2.当在同一个会话中进行了增删语句之后,一级缓存会失效

     例如当在上述例子中的第二部修改为删除的一条语句,一级缓存会失效

    可以看出在第二部进行删除操作后,1~3步骤都对数据库进行操作,所以在进行增删的操作后,执行相同的查询语句,一级缓存会失效。

  3.原理见图(欢迎指正)

  4.SqlSession 方法解析:

    SqlSession中提供了与数据交互的方法

  <T> T selectOne(String var1);

  <T> T selectOne(String var1, Object var2);

  <E> List<E> selectList(String var1);

  <E> List<E> selectList(String var1, Object var2);

  <E> List<E> selectList(String var1, Object var2, RowBounds var3);

  <K, V> Map<K, V> selectMap(String var1, String var2);

  <K, V> Map<K, V> selectMap(String var1, Object var2, String var3);

  <K, V> Map<K, V> selectMap(String var1, Object var2, String var3, RowBounds var4);

  <T> Cursor<T> selectCursor(String var1);

  <T> Cursor<T> selectCursor(String var1, Object var2);

  <T> Cursor<T> selectCursor(String var1, Object var2, RowBounds var3);

  void select(String var1, Object var2, ResultHandler var3);

  void select(String var1, ResultHandler var2);

  void select(String var1, Object var2, RowBounds var3, ResultHandler var4);

  int insert(String var1);

  int insert(String var1, Object var2);

  int update(String var1);

  int update(String var1, Object var2);

  int delete(String var1);

  int delete(String var1, Object var2);

  void commit();

  void commit(boolean var1);

  void rollback();

  void rollback(boolean var1);

  List<BatchResult> flushStatements();

  void close();

  void clearCache();

  Configuration getConfiguration();

  <T> T getMapper(Class<T> var1);

  Connection getConnection();

  Executor是与操作数据库有关的职责都会被委托。Executor有若干个实现类,为Executor赋予了不同的能力,之后参考源码进行深入学习。

  5.至此,通过源码的分析一个简单的上述案例的原因(insert/delete/update方法,缓存就会刷新的原因)

    SqlSession的insert方法和delete方法,都会统一走update的流程,代码如下所示:

  @Override

  public int insert(String statement, Object parameter) { return update(statement, parameter);   }

   @Override   public int delete(String statement) { return update(statement, null);   }

  update方法也是委托给了Executor执行。BaseExecutor的执行方法如下所示。

  @Override

  public int update(MappedStatement ms, Object parameter) throws SQLException {     ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());

     if (closed) {

       throw new ExecutorException("Executor was closed.");     }       clearLocalCache();

        return doUpdate(ms, parameter);   }

  每次执行update前都会清空localCache。

mybatis一级缓存:

MyBatis一级缓存的生命周期和SqlSession一致。

MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。

MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为Statement。

(未完待续......)

  之后一遍介绍mybatis的二级缓存,请期待......

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JavaEdge

用弱引用堵住内存泄漏全局 Map 造成的内存泄漏找出内存泄漏HPROF 输出,显示 Map.Entry 对象的分配点弱引用WeakReference.get() 的一种可能实现用 WeakHashMa

3635
来自专栏xiaoheike

hibernate persist update 方法没有正常工作(不保存数据,不更新数据)

在工程中通过spring aop的方式配置事务,使用hibernate做持久化。在代码实现中使用hibernate persit()方法插入数据到数据库,使用h...

1601
来自专栏向治洪

Android ClassLoader详解

我们知道不管是插件化还是组件化,都是基于系统的ClassLoader来设计的。只不过Android平台上虚拟机运行的是Dex字节码,一种对class文件优化的产...

32510
来自专栏Java呓语

单元测试以及JUnit框架解析

我们都有个习惯,常常不乐意去写个简单的单元测试程序来验证自己的代码。对自己的程序一直非常有自信,或存在侥幸心理每次运行通过后就直接扔给测试组测试了。然而每次测试...

1572
来自专栏進无尽的文章

简述OC语言

对于一门语言的学习是需要时间领悟的,而对于一些原理性的问题,我们需要清楚其核心思想,知其然而知其所以然,这样才能有利于自己的后续发展。本文只是简述,没有面面具到...

2292
来自专栏青玉伏案

iOS逆向工程之Hopper中的ARM指令

虽然前段时间ARM被日本软银收购了,但是科技是无国界的,所以呢ARM相关知识该学的学。现在看ARM指令集还是倍感亲切的,毕竟大学里开了ARM这门课,并且做了不少...

3407
来自专栏企鹅号快讯

优秀的持久层框架-Mybatis框架解析

Topic Mybatis步骤 mybatis解决原生态jdbc的问题 数据库连接,使用时连接,不使用时释放,对数据库进行频繁连接的开启和关闭,造成数据库资源浪...

2119
来自专栏编程

身为程序猿,怎能不懂RegExp?

正则表达式是程序猿的好朋友。这体现在两个方面:一、在我们敲的代码里面,可以用正则表达式非常轻巧、灵便、快捷的完成字符串的操作,比如匹配、搜索、提取子串等。二、我...

2155
来自专栏Java学习网

Java阻塞队列线程集控制的实现方法

Java阻塞队列线程集控制的实现方法 队列以一种先进先出的方式管理数据。如果你试图向一个已经满了的阻塞队列中添加一个元素,或是从一个空的阻塞队列中移除一个元素...

3158
来自专栏大内老A

一个通过JSONP跨域调用WCF REST服务的例子(以jQuery为例)

JSONP(JSON with Padding)可以看成是JSON的一种“使用模式”,用以解决“跨域访问”的问题,这篇简单的文章给出一个简单的例子用于模拟如何通...

2117

扫码关注云+社区

领取腾讯云代金券