Mybatis源码研究7:缓存的设计和实现

2014年11月19日 21:02:14 酷酷的糖先森 阅读数:1020
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014723529/article/details/41288565

一、包概述(org.apache.ibatis.cache)

本包包含了Mybatis框架的缓存接口的定义和实现。
 
 本包只引用了Mybatis的io包的Resources,不依赖于任何第三方库。
 
 Mybatis的其它包大量引用了本包中的类和接口,即严重依赖于本包。
 
 
 二、类和接口概述
 
 缓存框架按照 Key-Value方式存储,Key的生成采取规则为:[hashcode:checksum:mappedStementId:offset:limit:executeSql:queryParams]。
 
 
 Cache接口定义了缓存接口。

CacheKey定义了缓存的Key。
 PerpetualCache直接实现了Cache接口。
 
 FifoCache,LoggingCache,LruCache,ScheduledCache,SerializedCache,SoftCache,SynchronizedCache,
 TransactionalCache,WeakCache 采用装饰模式实现Cache接口。
 
 采用装饰模式,一个个包装起来,形成一个链,典型的就是SynchronizedCache->LoggingCache->SerializedCache->LruCache->PerpetualCache,通过链起来达到功能增加。
 
 CacheException定义了缓存异常。
 
 三、缓存接口的定义

public interface Cache {
 // 缓存实现类的id
 String getId();

// 缓存的对象的个数
 int getSize();

// 放入一个缓存对象
 void putObject(Object key, Object value);

// 获得一个缓存对象
 Object getObject(Object key);

// 删除一个缓存对象
 Object removeObject(Object key);

// 清空缓存对象
 void clear();

// 获取读写锁
 ReadWriteLock getReadWriteLock();

}

 四、缓存Key的设计
 
   一般缓存框架的数据结构基本上都是 Key-Value方式存储。 MyBatis对于其Key的生成采取规则为:

[hashcode:checksum:mappedStementId :offset:limit:executeSql:queryParams]。

(待深入研究和完善)

 五、缓存实现类和包装类

实现类:PerpetualCache, 永久缓存,一旦存入就一直保持,内部就是一个HashMap,所有方法基本就是直接调用HashMap的方法。

内部维护一个Map数据结构,private Map<Object, Object> cache = new HashMap<Object, Object>();

包装类:

FifoCache:先进先出缓存,内部就是一个链表,将链表开头元素(最老)移除。

LoggingCache:日志缓存,添加功能:取缓存时打印命中率。

LruCache:最近最少使用缓存,核心就是覆盖 LinkedHashMap.removeEldestEntry方法,返回true或false告诉 LinkedHashMap要不要删除此最老键值。
LinkedHashMap内部其实就是每次访问或者插入一个元素都会把元素放到链表末尾,这样不经常访问的键值肯定就在链表开头啦。

ScheduledCache:定时调度缓存, 目的是每一小时清空一下缓存。

SerializedCache:序列化缓存,用途是先将对象序列化成2进制,再缓存向缓存中 put或get数据时的序列化及反序列化处理。、

SoftCache:软引用缓存,核心是SoftReference。

SynchronizedCache:同步缓存,防止多线程问题。
核心: 加读写锁,     ReadWriteLock.readLock().lock()/unlock() ,ReadWriteLock.writeLock().lock()/unlock()

对于 Lock机制来说,其分为 Read 和 Write 锁,其 Read 锁允许多个线程同时持有,而 Write 锁,一次能被一个线程持有,如果当 Write 锁没有释放,其它需要 Write的线程只能等待其释放才能去持有。

TransactionalCache:

事务缓存,一次性存入多个缓存,移除多个缓存 。
 
  我们可以看到在TransactionalCache类里也维护着两个HashMap:
  entriesToAddOnCommit和entriesToRemoveOnCommit。
  
  当在TransactionalCacheManager中调用putObject和removeObject方法的时候并不是马上就把对象存放到缓存或者从缓存中删除  ,而是先把这个对象放到这两个HashMap之中的一个里,然后当执行commit方法时再真正地把对象存放到缓存或者从缓存中删除。
  
  现在我们应该可以明白为TransactionalCacheManager和TransactionalCache这两个类要加上事务的前缀了,因为commit方法是一个原子操作,一次会操作多个对象,要么一起成功,要么就一起失败。

WeakCache:弱引用缓存,核心是WeakReference。
 
 六、缓存实现的问题和解决方案(待深入研究和完善)

问题:

1.作为缓存中对象的key是它的CacheKey对象。

不得不说这是一个失败的设计,key值的类型是String类型就已经足够了,完全没有必要用对象类型来做key值的类型。

因为内存空间是有限的,要在有限的空间中尽可能地存放更多的内容,就需要key值在保证唯一性的情况下空间占的越小越好。

2.myBatis的读写锁有写饥渴问题等,这些问题都会给性能造成影响。
   
    所以还是不建议在生产环境中使用iBatis或者myBatis自带的二级缓存,只使用他们的ORM功能,而二级缓存还是交给Memcached等其它缓存框架来实现吧。

memcache:http://baike.baidu.com/view/1193094.htm
 
 oscache:http://baike.baidu.com/view/1835163.htm
 
 ehcache:http://baike.baidu.com/view/1866754.htm

转载于:https://www.cnblogs.com/hfultrastrong/p/10971636.html

Mybatis源码研究7:缓存的设计和实现相关推荐

  1. Mybatis源码研究序

    公司开发项目中,用到了Mybatis这个框架.所以,开始了对Mybatis的认真学习-应用-研究. DbUtils,Mybatis,Struts2,Hibernate3,Spring3 的源码都瞧了瞧 ...

  2. Mybatis源码研究2:框架整体设计

    本文转载自:http://chenjc-it.iteye.com/blog/1460990 1.引言 本文主要讲解Mybatis的整体程序设计,理清楚框架的主要脉络.后面文章我们再详细讲解各个组件. ...

  3. Mybatis源码研究6:元数据(metadata)

    2019独角兽企业重金招聘Python工程师标准>>> 原理分析之六:元数据(metadata)   一.依赖关系  本包对mybatis的其它包没有任何依赖,mybatis的其它包 ...

  4. Mybatis源码研究5:数据源的实现

    2019独角兽企业重金招聘Python工程师标准>>> 一.数据源概述 数据源相关核心类位于datasource包中,本包主要引用了Mybatis的reflection的Except ...

  5. mondrian 源码研究之 缓存数据的加载、初始化

    前言: 在mondrian中,所有数据的来源都是聚集层,储存层把mdx语句生成的sql执行完后,再到聚集层中做整理,存入外部缓存. 今天要讲的类: SegmentLoader.java. 主要说下  ...

  6. Mybatis源码学习笔记之Mybatis二级缓存

    简介   Mybatis一级缓存是会话级的缓存,而二级缓存则是应用级别的缓存,默认关闭,二级缓存使用不慎可能会导致脏读. 开启方式(SpringBoot+Mybatis)   application. ...

  7. MyBatis源码-深入理解MyBatis Executor的设计思想

    文章目录 Pre JDBC的执行过程 JDBC Demo JDBC Statement 接口 MyBatis执行过程 四大组件 组件之间的关系 Executor 执行器组件 架构总览 接口继承关系 P ...

  8. java毕业设计健民中医药方网设计mybatis+源码+调试部署+系统+数据库+lw

    java毕业设计健民中医药方网设计mybatis+源码+调试部署+系统+数据库+lw java毕业设计健民中医药方网设计mybatis+源码+调试部署+系统+数据库+lw 本源码技术栈: 项目架构:B ...

  9. java毕业设计基于Web的人事管理系统的设计与实现mybatis+源码+调试部署+系统+数据库+lw

    java毕业设计基于Web的人事管理系统的设计与实现mybatis+源码+调试部署+系统+数据库+lw java毕业设计基于Web的人事管理系统的设计与实现mybatis+源码+调试部署+系统+数据库 ...

  10. 计算机毕业设计JAVA基于的校园头条新闻管理系统的设计与实现mybatis+源码+调试部署+系统+数据库+lw

    计算机毕业设计JAVA基于的校园头条新闻管理系统的设计与实现mybatis+源码+调试部署+系统+数据库+lw 计算机毕业设计JAVA基于的校园头条新闻管理系统的设计与实现mybatis+源码+调试部 ...

最新文章

  1. Android getDrawable 直接使用 提示要求API为21 的处理方法
  2. MySQL基础之增删改查
  3. GB编码与UTF8编码的转换【转载】
  4. mysql语法学习(一)__Instances__表
  5. 选哪个云计算平台部署自己的网站?
  6. java基础入门答案谭晓芳,原理+实战讲解
  7. 形状相似的物品_空运一般货物及危险品和特殊物品对包装的要求和规定!
  8. 用sqoop将mysql的数据导入到hive表中,原理分析
  9. MMSegmentation:标准统一的语义分割框架
  10. 【毕业答辩】怎样做好毕业答辩?纯干货
  11. laravel 事件及监听
  12. 八、关于FFmpeg需要絮叨的一些事
  13. 测试用例文档_如何设计测试用例
  14. 印象笔记如何与微信连接到服务器,如何保存微信和微博到印象笔记?
  15. Oracle中的LOB字段解读
  16. Stratified Transformer复现和调试记录,ubuntu20复现S3DIS数据集(点云语义分割)
  17. 去哪儿12306候补购票怎么用?
  18. 禁止触摸屏触控板手指缩放,需要这样处理
  19. 使用EditPlus技巧
  20. 北大国际医院:基于互联网医疗的移动诊疗方案分析与设计

热门文章

  1. vs 通过命令参数 定义宏_YRC1000 宏程序命令(四十)
  2. day22 随机输出ArrayList
  3. ES6 系列之我们来聊聊装饰器
  4. 图的存储结构之十字链表、邻接多重表、边集数组
  5. 20170314--服务器监控
  6. Java编程思想1-对象导论
  7. REST another WebService???
  8. shell脚本如何显示所执行的每一条命令
  9. org manual翻译--2.7 纯文本列表
  10. 全面综合的管理平台,让所有网络都有管理员