开启mybatis日志_Mybatis源码分析之Cache二级缓存原理 (五)
一: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二级缓存原理 (五)相关推荐
- Android源码分析—属性动画的工作原理
转载请注明出处: http://blog.csdn.net/singwhatiwanna/article/details/17853275 前言 本文为Android动画系列的最后一篇文章,通过对源码 ...
- mybatis plus 批量保存_mybatis源码分析
原理图: Configuration解析: Configuration表示配置,该对象中维护了很多mybatis的配置参数: 大致可分为四部分:1.环境变量Environment 2.配置参数:3.缓 ...
- MyBatis学习笔记-源码分析篇
引言 SQL 语句的执行涉及多个组件,其中比较重要的是 Executor. StatementHandler. ParameterHandler 和 ResultSetHandler. Executo ...
- Lifecycle 使用与源码分析——彻底搞懂Lifecycle原理
一.Lifecycle 介绍 Lifecycle是一个生命周期感知组件,一般用来响应Activity.Fragment等组件的生命周期变化,并将变化通知到已注册的观察者.有助于更好地组织代码,让代码逻 ...
- 源码分析 Sentinel 实时数据采集实现原理
本篇将重点关注 Sentienl 实时数据收集,即 Sentienl 具体是如何收集调用信息,以此来判断是否需要触发限流或熔断. 本节目录 1.源码分析 StatisticSlot 1.1 Stati ...
- 极光实时监听怎么调用_源码分析 Sentinel 实时数据采集实现原理(图文并茂)
本篇将重点关注 Sentienl 实时数据收集,即 Sentienl 具体是如何收集调用信息,以此来判断是否需要触发限流或熔断. Sentienl 实时数据收集的入口类为 StatisticSlot. ...
- Android属性动画赏析,Android源码分析—属性动画的工作原理
前言 本文为Android动画系列的最后一篇文章,通过对源码的分析,能够让大家更深刻地理解属性动画的工作原理,这有助于我们更好地使用属性动画.但是,由于动画的底层实现已经深入到jni层,并且涉及到显示 ...
- Mybatis概念以及源码分析
1.什么是 Mybatis? (1)Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时只需要关 注 SQL 语句本身,不需要花费精力去处理加载驱动.创建连接.创建 s ...
- pm2 多个线程输出一个日志_PM2 源码分析
近期有需求需要了解 PM2 一些功能的实现方式,所以趁势看了一下 PM2 的源码,也算是用了这么多年的 PM2,第一次进入内部进行一些探索. PM2 是一个 基于 node.js 的进程管理工具,本身 ...
最新文章
- 习题5-5 使用函数统计指定数字的个数 (15 分)
- TinyMCE的使用
- 实验室之函数计算专场,完成任务,领精美好礼!
- 2014-07-28 使用Axure RP进行手机端BBS的原型设计
- 百度Q2智能云增长强劲;据悉史上最大 AI 芯片诞生!中兴与奇瑞成立合资公司一起加快开发5G汽车……...
- filebeat + logstash 发送日志至kafka 入门
- 【codevs3304】水果姐逛水果店Ⅰ,线段树练习
- java qq在线客服,Java获得腾讯QQ在线状态(.net webservice) | 学步园
- Linux怎样创建FTP服务器--修改用户默认目录-完美解决 - 费元星
- Behavior Creator 行为树可视化编辑器
- MATLAB中Imcrop函数的用法
- 在线分析仪器(一)概述
- ubuntu 16.04.7通过get-pip.py安装pip 20.3.4
- 软件工程第4次作业------石墨文档Android客户端案例分析
- 《前端框架Vue.js》
- vmware安装打印机(win10)
- 人工智能为教育创新赋能,开启教学新模式
- ERROR 1130: Host xxx.xxx.xxx.xxx is not allowed to connect to this MySQL server
- 双离合档把上按钮作用_大众车自动档档把上的按钮是干什么用的?
- 04-C语言如何返回两个甚至多个值?
热门文章
- Flume 1.7 源码分析(五)从Channel获取数据写入Sink
- 容器源码分析之HashTable(八)
- BSP细分时代即将来临
- 【解题报告】Leecode 237. 删除链表中的节点——Leecode每日一题系列
- redo日志写入为什么“俩阶段提交”
- java api中最常用的五个包_java 5 个常用的api包
- linux命令行下载github文件,Linux命令行下使用GitHub
- 台式计算机序列号在哪,台式机如何查看序列号
- Linux基础优化方法(一)———优化命令提示符和yum源仓库
- iphone电池怎么保养_蓄电池在ups系统中应该怎么维护保养?