mybatis缓存LruCache源码分析

2024-08-21 02:58

本文主要是介绍mybatis缓存LruCache源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

LruCache

  • LruCache是如何实现的
  • linkedHashMap源码分析
    • 双向链表
      • 链表优点
      • 链表缺点
      • 双向链表节点
      • 移动节点到链表的尾部
    • 为什么要散列表和链表搭配使用

LruCache是如何实现的

LruCache的关键代码:

public class LruCache implements Cache {private final Cache delegate;private Map<Object, Object> keyMap;private Object eldestKey;public LruCache(Cache delegate) {this.delegate = delegate;// 设置缓存的键值对最大数量setSize(1024);}public void setSize(final int size) {/*** 重写方法:是否移除最老的链表节点,最老的链表节点就是链表的头节点*/keyMap = new LinkedHashMap<Object, Object>(size, .75F, true) {private static final long serialVersionUID = 4267176411845948333L;@Overrideprotected boolean removeEldestEntry(Map.Entry<Object, Object> eldest) {// 判断什么时候需要移除最老的节点boolean tooBig = size() > size;if (tooBig) {// 保存最老的链表节点的key,方便cycleKeyList()删除相应的keyeldestKey = eldest.getKey();}return tooBig;}};}@Overridepublic Object getObject(Object key) {// 虽然没有使用这个返回值,但是需要更细linkedHashMap的使用情况keyMap.get(key); // touchreturn delegate.getObject(key);}private void cycleKeyList(Object key) {/*** 这个方法会更新eldestKey的值* 此方法在hashMap当中,调用过程:hashmap.put()->linkedHashMap.afterNodeInsertion()->linkedHashMap.removeEldestEntry()* 最终eldestKey的值被更新*/keyMap.put(key, key);// 如果eldestKey的值被更新,则需要到真正存储缓存的地方删除键值对if (eldestKey != null) {delegate.removeObject(eldestKey);eldestKey = null;}}}

linkedHashMap源码分析

双向链表

链表优点

  1. 插入,删除,新增操作的时间复杂度都是O(1)
  2. 可以利用不连续的内存空间

链表缺点

  1. 不能随机查找,随机查找的时间复杂度是o(n)
  2. 因为要保存前后节点的引用,所以占用的内存空间会变大

双向链表节点

/*** 继承了HashMap.Node* 其实就是在hashMap节点的基础上加入before和after节点* 构成了双向链表的节点* @param <K>* @param <V>*/static class Entry<K,V> extends HashMap.Node<K,V> {Entry<K,V> before, after;Entry(int hash, K key, V value, Node<K,V> next) {super(hash, key, value, next);}}

移动节点到链表的尾部

当get()被调用了,当前节点就变成最新被访问的了,需要移动到链表的尾部

void afterNodeAccess(Node<K,V> e) { // move node to lastLinkedHashMap.Entry<K,V> last;/*** 两个判断逻辑:* 1 链表是否支持按照最近最新使用规则排序,默认按照插入顺序排序* 2 当前节点是否已经是尾节点了*/if (accessOrder && (last = tail) != e) {LinkedHashMap.Entry<K,V> p =(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;p.after = null;if (b == null) // 说明当前节点是headhead = a; //重新定义head elseb.after = a; // 重新定义p.before的指向if (a != null) a.before = b; // 重新定义p.after的指向else // a==null说明b已经是尾节点了last = b;if (last == null) // 说明当前链表为空head = p;else {   // 定义新的为节点p.before = last;last.after = p;}// 新的尾节点产生,可以看出移动链表的节点不需要通过遍历链表tail = p;++modCount;}}

为什么要散列表和链表搭配使用

针对链表不能随机访问的缺点,如果使用散列表随机访问时间复杂度为O(1)的有点,两者扬长避短,充分发挥各自的优势

这样一来,可以创建有序的map键值对

public class LinkedHashMap<K,V>extends HashMap<K,V>implements Map<K,V>

这篇关于mybatis缓存LruCache源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1091929

相关文章

MyBatis分页查询实战案例完整流程

《MyBatis分页查询实战案例完整流程》MyBatis是一个强大的Java持久层框架,支持自定义SQL和高级映射,本案例以员工工资信息管理为例,详细讲解如何在IDEA中使用MyBatis结合Page... 目录1. MyBATis框架简介2. 分页查询原理与应用场景2.1 分页查询的基本原理2.1.1 分

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

mybatis映射器配置小结

《mybatis映射器配置小结》本文详解MyBatis映射器配置,重点讲解字段映射的三种解决方案(别名、自动驼峰映射、resultMap),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定... 目录select中字段的映射问题使用SQL语句中的别名功能使用mapUnderscoreToCame

mybatis-plus如何根据任意字段saveOrUpdateBatch

《mybatis-plus如何根据任意字段saveOrUpdateBatch》MyBatisPlussaveOrUpdateBatch默认按主键判断操作类型,若需按其他唯一字段(如agentId、pe... 目录使用场景方法源码方法改造首先在service层定义接口service层接口实现总结使用场景my

MyBatis ParameterHandler的具体使用

《MyBatisParameterHandler的具体使用》本文主要介绍了MyBatisParameterHandler的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一、概述二、源码1 关键属性2.setParameters3.TypeHandler1.TypeHa

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本

使用Spring Cache本地缓存示例代码

《使用SpringCache本地缓存示例代码》缓存是提高应用程序性能的重要手段,通过将频繁访问的数据存储在内存中,可以减少数据库访问次数,从而加速数据读取,:本文主要介绍使用SpringCac... 目录一、Spring Cache简介核心特点:二、基础配置1. 添加依赖2. 启用缓存3. 缓存配置方案方案

Java实现本地缓存的四种方法实现与对比

《Java实现本地缓存的四种方法实现与对比》本地缓存的优点就是速度非常快,没有网络消耗,本地缓存比如caffine,guavacache这些都是比较常用的,下面我们来看看这四种缓存的具体实现吧... 目录1、HashMap2、Guava Cache3、Caffeine4、Encache本地缓存比如 caff

MyBatis-Plus 与 Spring Boot 集成原理实战示例

《MyBatis-Plus与SpringBoot集成原理实战示例》MyBatis-Plus通过自动配置与核心组件集成SpringBoot实现零配置,提供分页、逻辑删除等插件化功能,增强MyBa... 目录 一、MyBATis-Plus 简介 二、集成方式(Spring Boot)1. 引入依赖 三、核心机制

MyBatis的xml中字符串类型判空与非字符串类型判空处理方式(最新整理)

《MyBatis的xml中字符串类型判空与非字符串类型判空处理方式(最新整理)》本文给大家介绍MyBatis的xml中字符串类型判空与非字符串类型判空处理方式,本文给大家介绍的非常详细,对大家的学习或... 目录完整 Hutool 写法版本对比优化为什么status变成Long?为什么 price 没事?怎