一:Cache类的介绍

讲解缓存之前我们需要先了解一下Cache接口以及实现MyBatis定义了一个org.apache.ibatis.cache.Cache接口作为其Cache提供者的SPI(ServiceProvider Interface) ,所有的MyBatis内部的Cache缓存,都应该实现这一接口

Cache的实现类中,Cache有不同的功能,每个功能独立,互不影响,则对于不同的Cache功能,这里使用了装饰者模式实现。

看下cache的实现类,如下图:

1.FIFOCache:先进先出算法 回收策略,装饰类,内部维护了一个队列,来保证FIFO,一旦超出指定的大小,则从队列中获取Key并从被包装的Cache中移除该键值对。

2.LoggingCache:输出缓存命中的日志信息,如果开启了DEBUG模式,则会输出命中率日志。

3.LruCache:最近最少使用算法,缓存回收策略,在内部保存一个LinkedHashMap

4.ScheduledCache:定时清空Cache,但是并没有开始一个定时任务,而是在使用Cache的时候,才去检查时间是否到了。

5.SerializedCache:序列化功能,将值序列化后存到缓存中。该功能用于缓存返回一份实例的Copy,用于保存线程安全。

6.SoftCache:基于软引用实现的缓存管理策略,软引用回收策略,软引用只有当内存不足时才会被垃圾收集器回收

7.SynchronizedCache:同步的缓存装饰器,用于防止多线程并发访问

8.PerpetualCache 永久缓存,一旦存入就一直保持,内部就是一个HashMap

9.WeakCache:基于弱引用实现的缓存管理策略

10.TransactionalCache 事务缓存,一次性存入多个缓存,移除多个缓存

11.BlockingCache 可阻塞的缓存,内部实现是ConcurrentHashMap

二:二级缓存初始化

Mybatis默认对二级缓存是关闭的,一级缓存默认开启,如果需要开启只需在mapper上加入

二级缓存是怎么初始化的呢?

我们在之前的文章里面(Mybatis源码分析之SqlSessionFactory(一))分析了配置文件的加载,我们回到那边来找到二级缓存的加载地方,一开始我就说了“如果需要开启只需在mapper上加入

XMLConfigBuilder.parse-->parseConfiguration(XNode root)-->mapperElement(root.evalNode("mappers"))-->mapperElement(XNode parent)

看下mapperElement的方法

private void mapperElement(XNode parent) throws Exception {if (parent != ) {for (XNode child : parent.getChildren) {if ("package".equals(child.getName)) {String mapperPackage = child.getStringAttribute("name");configuration.addMappers(mapperPackage);} else {String resource = child.getStringAttribute("resource");String url = child.getStringAttribute("url");String mapperClass = child.getStringAttribute("class");if (resource != && url == && mapperClass == ) {ErrorContext.instance.resource(resource);InputStream inputStream = Resources.getResourceAsStream(resource);XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments);mapperParser.parse;} else if (resource == && url != && mapperClass == ) {ErrorContext.instance.resource(url);InputStream inputStream = Resources.getUrlAsStream(url);XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments);mapperParser.parse;} else if (resource == && url == && mapperClass != ) {Class mapperInterface = Resources.classForName(mapperClass);configuration.addMapper(mapperInterface);} else {throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");}}}}}

这个时候我已经找到了mapper节点了,我们在看向前走

XMLMapperBuilder.mapperParser.parse

代码如下

public void parse {if (!configuration.isResourceLoaded(resource)) {configurationElement(parser.evalNode("/mapper"));configuration.addLoadedResource(resource);bindMapperForNamespace;}parsePendingResultMaps;parsePendingChacheRefs;parsePendingStatements;}

看到configurationElement(parser.evalNode("/mapper"));看到mapper节点了继续走

 private void configurationElement(XNode context) {try {String namespace = context.getStringAttribute("namespace");if (namespace == || namespace.equals("")) {throw new BuilderException("Mapper's namespace cannot be empty");}builderAssistant.setCurrentNamespace(namespace);cacheRefElement(context.evalNode("cache-ref"));cacheElement(context.evalNode("cache"));parameterMapElement(context.evalNodes("/mapper/parameterMap"));resultMapElements(context.evalNodes("/mapper/resultMap"));sqlElement(context.evalNodes("/mapper/sql"));buildStatementFromContext(context.evalNodes("select|insert|update|delete"));} catch (Exception e) {throw new BuilderException("Error parsing Mapper XML. Cause: " + e, e);}}

到这里终于见到了他cacheElement(context.evalNode("cache"));

看源码

 private void cacheElement(XNode context) throws Exception {if (context != ) {String type = context.getStringAttribute("type

开启mybatis日志_Mybatis源码分析之Cache二级缓存原理 (五)相关推荐

  1. Android源码分析—属性动画的工作原理

    转载请注明出处: http://blog.csdn.net/singwhatiwanna/article/details/17853275 前言 本文为Android动画系列的最后一篇文章,通过对源码 ...

  2. mybatis plus 批量保存_mybatis源码分析

    原理图: Configuration解析: Configuration表示配置,该对象中维护了很多mybatis的配置参数: 大致可分为四部分:1.环境变量Environment 2.配置参数:3.缓 ...

  3. MyBatis学习笔记-源码分析篇

    引言 SQL 语句的执行涉及多个组件,其中比较重要的是 Executor. StatementHandler. ParameterHandler 和 ResultSetHandler. Executo ...

  4. Lifecycle 使用与源码分析——彻底搞懂Lifecycle原理

    一.Lifecycle 介绍 Lifecycle是一个生命周期感知组件,一般用来响应Activity.Fragment等组件的生命周期变化,并将变化通知到已注册的观察者.有助于更好地组织代码,让代码逻 ...

  5. 源码分析 Sentinel 实时数据采集实现原理

    本篇将重点关注 Sentienl 实时数据收集,即 Sentienl 具体是如何收集调用信息,以此来判断是否需要触发限流或熔断. 本节目录 1.源码分析 StatisticSlot 1.1 Stati ...

  6. 极光实时监听怎么调用_源码分析 Sentinel 实时数据采集实现原理(图文并茂)

    本篇将重点关注 Sentienl 实时数据收集,即 Sentienl 具体是如何收集调用信息,以此来判断是否需要触发限流或熔断. Sentienl 实时数据收集的入口类为 StatisticSlot. ...

  7. Android属性动画赏析,Android源码分析—属性动画的工作原理

    前言 本文为Android动画系列的最后一篇文章,通过对源码的分析,能够让大家更深刻地理解属性动画的工作原理,这有助于我们更好地使用属性动画.但是,由于动画的底层实现已经深入到jni层,并且涉及到显示 ...

  8. Mybatis概念以及源码分析

    1.什么是 Mybatis? (1)Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时只需要关 注 SQL 语句本身,不需要花费精力去处理加载驱动.创建连接.创建 s ...

  9. pm2 多个线程输出一个日志_PM2 源码分析

    近期有需求需要了解 PM2 一些功能的实现方式,所以趁势看了一下 PM2 的源码,也算是用了这么多年的 PM2,第一次进入内部进行一些探索. PM2 是一个 基于 node.js 的进程管理工具,本身 ...

最新文章

  1. 习题5-5 使用函数统计指定数字的个数 (15 分)
  2. TinyMCE的使用
  3. 实验室之函数计算专场,完成任务,领精美好礼!
  4. 2014-07-28 使用Axure RP进行手机端BBS的原型设计
  5. 百度Q2智能云增长强劲;据悉史上最大 AI 芯片诞生!中兴与奇瑞成立合资公司一起加快开发5G汽车……...
  6. filebeat + logstash 发送日志至kafka 入门
  7. 【codevs3304】水果姐逛水果店Ⅰ,线段树练习
  8. java qq在线客服,Java获得腾讯QQ在线状态(.net webservice) | 学步园
  9. Linux怎样创建FTP服务器--修改用户默认目录-完美解决 - 费元星
  10. Behavior Creator 行为树可视化编辑器
  11. MATLAB中Imcrop函数的用法
  12. 在线分析仪器(一)概述
  13. ubuntu 16.04.7通过get-pip.py安装pip 20.3.4
  14. 软件工程第4次作业------石墨文档Android客户端案例分析
  15. 《前端框架Vue.js》
  16. vmware安装打印机(win10)
  17. 人工智能为教育创新赋能,开启教学新模式
  18. ERROR 1130: Host xxx.xxx.xxx.xxx is not allowed to connect to this MySQL server
  19. 双离合档把上按钮作用_大众车自动档档把上的按钮是干什么用的?
  20. 04-C语言如何返回两个甚至多个值?

热门文章

  1. Flume 1.7 源码分析(五)从Channel获取数据写入Sink
  2. 容器源码分析之HashTable(八)
  3. BSP细分时代即将来临
  4. 【解题报告】Leecode 237. 删除链表中的节点——Leecode每日一题系列
  5. redo日志写入为什么“俩阶段提交”
  6. java api中最常用的五个包_java 5 个常用的api包
  7. linux命令行下载github文件,Linux命令行下使用GitHub
  8. 台式计算机序列号在哪,台式机如何查看序列号
  9. Linux基础优化方法(一)———优化命令提示符和yum源仓库
  10. iphone电池怎么保养_蓄电池在ups系统中应该怎么维护保养?