范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

Mybatis的缓存讲解

  前段时间阿粉的一个朋友和阿粉吃饭,在吃饭的时候和阿粉疯狂的吐槽面试官,说面试官问的问题都是些什么问题呀,我一个干了三四年的开发,也不说问点靠谱的,阿粉很好奇,问题问完基础的,一般不都是根据你自己的简历进行提问么?而接下来他说的出来的问题,阿粉表示,阿粉需要继续学习了。
  Mybatis是什么?
  说到这个,读者大人们肯定心想,阿粉是在开玩笑么?你一个 Java 程序员,你不知道Mybatis是啥么?不就是个持久层的框架么,这东西有啥好说的呢?但是阿粉还是要给大家说。
  Mybatis是一个半自动 ORM(对象关系映射)框架,它内部封装了JDBC,加载驱动、创建连接、创建 statement 等繁杂的过程,我们开发的时候只需要关注如何编写 SQL 语句,而不用关心其他的。
  为什么说 Mybatis 是一个半自动 ORM 的框架呢?
  ORM,是Object和Relation之间的映射,而Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 框架,而Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
  这也是为什么有些面试官在面试初级程序员的时候,很喜欢说,你觉得 Mybatis , 和 Hibernate 都有什么优缺点,为啥你们选择使用的 Mybatis 而不选择使用 Hibernate 呢?
  我们都说了 Mybatis是什么了,接下来肯定需要说说面试官都问了什么问题,能让阿粉的朋友变得非常犹豫。  Mybatis的一级、二级缓存是什么你了解么?Mybatis 的一级缓存
  我们先说 Mybatis 的一级缓存,因为这是如果不手动配置,他是自己默认开启的一级缓存,一级缓存只是相对于同一个 SqlSession 而言,参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不会再次发送SQL到数据库。
  当我们面试的时候,说完这个,一般情况下,面试官一定会追问下去,毕竟技术就是要问到你的知识盲区才会停止。
  那我们就来画个图表示一下一级缓存
  那面试官肯定会说,直接从数据库查不就行了,为啥要一级缓存呢?
  当我们使用MyBatis开启一次和数据库的会话时, MyBatis 会创建出一个 SqlSession 对象表示一次与数据库之间的信息传递,在我们执行 SQL 语句的过程中,们可能会反复执行完全相同的查询语句,如果不采取一些措施,我们每一次查询都会查询一次数据库,而如果在极短的时间内做了很多次相同的查询操作,那么这些查询返回的结果很可能相同。
  也就是说,如果我们在短时间内,频繁的去执行一条 SQL ,查询返回的结果本来应该是改变了,但是我们查询出来的时候,会出现结果一致的情况,正是为了解决这种问题,也为了减轻数据库的开销,所以 Mybatis 默认开启了一级缓存。  Mybatis 的二级缓存
  Mybatis 的二级缓存一般如果你不对他进行设置,他是不会开启的,而二级缓存是什么呢?Mybatis 中的二级缓存实际上就是 mapper 级别的缓存,而这时候肯定会有人说,那么不同之间的 Mapper 是同一个缓存么?
  答案是否定的,他不是一个,Mapper 级别的缓存实际上就是相同的 Mapper 使用的是一个二级缓存,但是在二级缓存中,又有多个不同的 SqlSession ,而不同的 Mapper 之间的二级缓存也就是互相不会影响的。
  就类似下面的图
  这二级缓存是不是就看起来有点意思了?
  那怎么能够开启二级缓存呢?
  1.MyBatis 配置文件     
  2.MyBatis 要求返回的 POJO 必须是可序列化的
  3.Mapper 的 xml 配置文件中加入 标签
  既然我们想要了解这个二级缓存,那么必然,我们还得知道它里面的配置都有哪些含义。
  我们先从标签看起,然后从源码里面看都有哪些配置信息提供给我们使用:
  blocking  : 直译就是调度,而在 Mybatis 中,如果缓存中找不到对应的 key ,是否会一直 blocking ,直到有对应的数据进入缓存。
  eviction  : 缓存回收策略
  而缓存回收策略,在源码中是有直接体现的,那么他们分别都对应了什么形式呢?  typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class); typeAliasRegistry.registerAlias("FIFO", FifoCache.class); typeAliasRegistry.registerAlias("LRU", LruCache.class); typeAliasRegistry.registerAlias("SOFT", SoftCache.class); typeAliasRegistry.registerAlias("WEAK", WeakCache.class); PERPETUAL : 选择 PERPETUAL 来命名缓存,暗示这是一个最底层的缓存,数据一旦存储进来,永不清除.好像这种缓存不怎么受待见。  FIFO : 先进先出:按对象进入缓存的顺序来移除它们  LRU : 最近最少使用的:移除最长时间不被使用的对象。  SOFT : 软引用:移除基于垃圾回收器状态和软引用规则的对象。  WEAK : 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
  大家虽然看着 PERPETUAL 排在了第一位,但是它可不是默认的,在 Mybatis 的缓存策略里面,默认的是 LRU 。
  PERPETUAL  :
  源代码如下:  public class PerpetualCache implements Cache {   private final String id;   private Map cache = new HashMap<>();   public PerpetualCache(String id) {     this.id = id;   }
  恩?看着是不是有点眼熟,它怎么就只是包装了 HashMap ? 你还别奇怪,他还真的就是使用的 HashMap ,不得不说,虽然人家是使用的 HashMap ,但是那可是比咱们写的高端多了。
  既然使用 HashMap ,那么必然就会有Key,那么他们的Key是怎么设计的?
  CacheKey:  public class CacheKey implements Cloneable, Serializable {   private static final long serialVersionUID = 1146682552656046210L;   public static final CacheKey NULL_CACHE_KEY = new NullCacheKey();   private static final int DEFAULT_MULTIPLYER = 37;   private static final int DEFAULT_HASHCODE = 17;   private final int multiplier;   private int hashcode; //用于表示CacheKey的哈希码   private long checksum; //总和校验,当出现复合key的时候,分布计算每个key的哈希码,然后求总和   private int count;//当出现复合key的时候,计算key的总个数   // 8/21/2017 - Sonarlint flags this as needing to be marked transient.  While true if content is not serializable, this is not always true and thus should not be marked transient.   private List updateList;//当出现复合key的时候,保存每个key
  确实牛逼,至于内部如何初始化,如何进行操作,大家有兴趣的可以去阅读一下源码,导入个源码包,打开自己看一下。
  FIFO : 先进先出缓冲淘汰策略 public class FifoCache implements Cache {    private final Cache delegate; //被装饰的Cache对象   private final Deque keyList;//用于记录key 进入缓存的先后顺序   private int size;//记录了缓存页的上限,超过该值需要清理缓存(FIFO)    public FifoCache(Cache delegate) {     this.delegate = delegate;     this.keyList = new LinkedList<>();     this.size = 1024;   }
  在 FIFO 淘汰策略中使用了 Java 中的 Deque,而 Deque 一种常用的数据结构,可以将队列看做是一种特殊的线性表,该结构遵循的先进先出原则。Java中,LinkedList实现了Queue接口,因为LinkedList进行插入、删除操作效率较高。
  当你看完这个源码的时候,是不是就感觉源码其实也没有那么难看懂,里面都是我们已经掌握好的知识,只不过中间做了一些操作,进行了一些封装。
  LRU  : 最近最少使用的缓存策略
  而 LUR 算法,阿粉之前都说过,如果对这个算法感兴趣的话,文章地址给大家送上,经典的 LRU 算法,你真的了解吗?
  而我们需要看的源码则是在 Mybatis 中的源码,  public class LruCache implements Cache {    private final Cache delegate;   private Map keyMap;   private Object eldestKey;//记录最少被使用的缓存项key    public LruCache(Cache delegate) {     this.delegate = delegate;     setSize(1024);//重新设置缓存的大小,会重置KeyMap 字段 如果到达上限 则更新eldestKey   }     public void putObject(Object key, Object value) {       delegate.putObject(key, value);       // 删除最近未使用的key       cycleKeyList(key);     }
  SOFT : 基于垃圾回收器状态和软引用规则的对象
  在看到基于垃圾回收器的时候,阿粉就已经开始兴奋了,竟然有GC的事情,那还不赶紧看看,这如此高大上(装杯)的事情,来瞅瞅吧!  public class SoftCache implements Cache {   //在SoftCache 中,最近使用的一部分缓存项不会被GC回收,这就是通过将其value添加到   private final Deque hardLinksToAvoidGarbageCollection;   //引用队列,用于记录GC回收的缓存项所对应的SoftEntry对象   private final ReferenceQueue queueOfGarbageCollectedEntries;   //底层被修饰的Cache 对象   private final Cache delegate;   //连接的个数,默认是256   private int numberOfHardLinks;    public SoftCache(Cache delegate) {     this.delegate = delegate;     this.numberOfHardLinks = 256;     this.hardLinksToAvoidGarbageCollection = new LinkedList<>();     this.queueOfGarbageCollectedEntries = new ReferenceQueue<>();   }      public void putObject(Object key, Object value) {       // 清除被GC回收的缓存项       removeGarbageCollectedItems();       // 向缓存中添加缓存项       delegate.putObject(key, new SoftEntry(key, value, queueOfGarbageCollectedEntries));     }    public Object getObject(Object key) {        Object result = null;        // 查找对应的缓存项        @SuppressWarnings("unchecked") // assumed delegate cache is totally managed by this cache        SoftReference softReference = (SoftReference) delegate.getObject(key);        if (softReference != null) {          result = softReference.get();          // 已经被GC 回收          if (result == null) {            // 从缓存中清除对应的缓存项            delegate.removeObject(key);          } else {            // See #586 (and #335) modifications need more than a read lock             synchronized (hardLinksToAvoidGarbageCollection) {              hardLinksToAvoidGarbageCollection.addFirst(result);              if (hardLinksToAvoidGarbageCollection.size() > numberOfHardLinks) {                hardLinksToAvoidGarbageCollection.removeLast();              }            }          }        }        return result;      }     public void clear() {         synchronized (hardLinksToAvoidGarbageCollection) {           // 清理强引用集合           hardLinksToAvoidGarbageCollection.clear();         }         // 清理被GC回收的缓存项         removeGarbageCollectedItems();         delegate.clear();       }     //其中指向key的引用是强引用,而指向value的引用是弱引用     private static class SoftEntry extends SoftReference {       private final Object key;          SoftEntry(Object key, Object value, ReferenceQueue garbageCollectionQueue) {         super(value, garbageCollectionQueue);         this.key = key;       }     }
  WEAK  : 基于垃圾收集器状态和弱引用规则的对象 public class WeakCache implements Cache {   private final Deque hardLinksToAvoidGarbageCollection;   private final ReferenceQueue queueOfGarbageCollectedEntries;   private final Cache delegate;   private int numberOfHardLinks;    public WeakCache(Cache delegate) {     this.delegate = delegate;     this.numberOfHardLinks = 256;     this.hardLinksToAvoidGarbageCollection = new LinkedList<>();     this.queueOfGarbageCollectedEntries = new ReferenceQueue<>();   }
  WeakCache在实现上与SoftCache几乎相同,只是把引用对象由SoftReference软引用换成了WeakReference弱引用。
  在这里阿粉也就不再多说了,关于 Mybatis 的二级缓存,你了解了么?下次遇到面试官问这个的时候,你应该知道怎么成功(装杯)不被打了吧。
7月MPV市场销量分析血流不止,何谈希望?由于不少车企在6月份(处理国五排车型)提前透支了部分下半年消费潜力,7月份各细分市场整体销量环比均出现2位数下跌。7月份,乘用车共售出148。5万辆,同比下降5。0。其中,轿车销量彩虹色的雨燕HidizsMS1彩虹版(Rainbow)林氏评测开门见山的说,这是一条定错了价的塞子,其前作MS1售价799,而这款MS1Rainbow(彩虹版)用了完全同款的单元,将外壳改成树脂材质,于是变得更轻盈腔体更小巧颜色更多彩,而素质新耳塞老魂魄海贝SeedsII海瓜子林氏评测初听这款外号为海瓜子的耳塞,不到一首歌的时候,我就眉头一皱,觉得事情并不简单。也不是说它的声场多宏大解析多致密导致我被震到,恰恰相反,一耳朵下去我反倒觉得它有点闷有点蒙着一层纱,与保守的品质与创新的态度铁三角CK3TW林氏评测日本这个国家着实是很有意思的。说保守,那很多方面真的是保守得不行,老规矩老习惯会一直留着,哪怕在别人看来没什么意义那种也都要坚守。顽固得让别人看不懂的事,他们做得多了去了。然而这地与众不同的质感JVCFW1800林氏评测一块招牌,如果总能连续引发足够多的期待值,那么一定意味着他们总能拿出值得期待的东西你比如说漫威这块招牌,但凡有个风吹草动说他们要出新片,话题度势必会被立刻引爆,万人翘首当然我知道有达音科SA3这塞子第一耳朵就让我想起TF10来这篇文章呢,我决定从TF10开始唠,原因很简单我初次听到达音科SA3的时候,第一耳朵就联想到了TF10,这俩塞子,是颇有神似之处的。大概齐十年前吧,当时对于玩耳机的那群人来说,定制守序中立即善良SoftearsRSV五单元动铁曾几何时,国产塞子是售价不过千的,几千几万那是美系日系的天下,舒尔威士顿音特美UE索尼铁三角AKG森海中高端塞子,那都人家的战场。究其原因,一方面是声音方面的技术,人家积累比较早也TANCHJIMDarling三单元圈铁,一种别样的张狂有些老爷车,是真的漂亮,那是一种张狂与精致并存的美感,每个细节都透着属于特定时代的自信与激昂。就包括Mini这种身上带有充分经典印记的现代作品,走在街上的回头率也是明显偏高的,所以威泽HE01这条塞子,诚意十足之余,更有两副不同面孔战狼2这种片子,早先我是真看不下去,太扯了因为,不过这一年下来,先是渔村那些破事儿,听着钢铁洪流进行曲看过阅兵,再经历新冠,此时脑子里的想法已经有了变化,反而真的就能平起平坐的把这演员和歌手海贝Crystal6六单元动铁耳塞评测在我还很小的时候,我会好奇一件事如果一个演员出身的人,他她去唱歌,那么他她唱歌的风格,会不会跟演戏时候比较像?或者反过来,歌手做演员,是不是往往也会有这种风格延续性?当时很懵懂嘛,守序中立即善良SoftearsRSV五单元动铁曾几何时,国产塞子是售价不过千的,几千几万那是美系日系的天下,舒尔威士顿音特美UE索尼铁三角AKG森海中高端塞子,那都人家的战场。究其原因,一方面是声音方面的技术,人家积累比较早也
我答ampampquot编程为什么不用中文?ampampquot中文API的意义和探索原问题的题目比较宽泛,先引用原问题的描述不要说什么中文难打,难记,难读之类的荒谬话语。也不要说关键字只有几十个。我一点不觉得那些for,if,,有什么价值。阅读代码的时候我希望尽量你没见过的Java入门,使用中文例程的教程之十二聊天机器人在聊天机器人目录中,是一个很简单的聊天机器人和客户端的实现。机器人回答和第十讲相同。尚欠细节说明。聊天服务类聊天机器人类编译运行服务器javac聊天机器人聊天服务类。javajav你没见过的Java入门,使用中文例程的教程之七造个人看到最后就知道上图意思。我们都是人类,每个人都是一个个体,大多数人有共有的属性和行为,同时也存在个体之间的差异。下面就来在程序里定义一个人类publicclass人这样的人还什么都618好物推荐科大讯飞智能录音笔SR101,办公学习都可以科技在进步,我们的学习和生活都离不开智能工具的辅助。比如录音笔,对于学生来说,可以帮助记录课堂内容便于复习而对于初入职场的小白来说,最怕的就是开会,会议记录让你手忙脚乱虽然公司配有论十四五政府投融资的新逻辑论十四五政府投融资的新逻辑。国庆节期间写了两篇财经文章发表于今日头条个人创作工作室,没想到获得了过万的阅读量,数百点赞,凭借流量今日头条还给予了10余元的创作奖励。今天,继论成功的你没见过的Java入门,使用中文例程的教程之八让它更像人一个人还有很多属性publicclass人String姓名无名氏int年龄0float身高0。0fprivateString小秘密publicvoid自我介绍()System。ou你没见过的Java入门,使用中文例程的教程之四文字提醒编程语言的语法是最机械的。在阅读过程中,请尽量关注于程序做了些什么,而一些语法细节可以暂时忽略。入门之后,在今后的读写代码过程中,语法自然会熟练起来。六文字之前的程序都用文字的ROttKRON乐旷多晶锆宝石耳机,时尚达人的潮流耳机单品当下,越来越多的年轻人热爱时尚以及鲜活个性的表达,同时,他们对美学主义也有着较为执着的追求。而ROttKRON乐旷推出的全球首款多晶锆宝石音腔真无线耳饰耳机,就很好地迎合了这一需求编程术语成系统中文化的意义本人在某问答网站的四千赞回答为什么有很多人执着于中文编程下有位分享关于中文变量名,在国内金融行业有一定的市场,因为直接用英文很多专业词汇没学这个专业即使专八也不一定知道,即使是美国LingOS灵犀系统首次亮相,全球银标正式迈入2。0全链路生态时代9月16日,上汽通用五菱在浙江乌镇召开了五菱品牌之夜发布会,在发布会现场,由上汽通用五菱自研为主,集成博泰思必驰科大讯飞等业内顶尖优质资源开发的一款全新的开放智能生态系统LingO买到就是赚到,呼伦贝尔宋ProEV最高优惠1。0万元今天给大家推荐一款车它就是宋ProEV,特别适合日常使用,据悉比亚迪王朝呼伦贝尔益丰祥泰店10。2910。29限时回馈用户,降价1。0万元,对宋ProEV感兴趣的朋友不妨亲自体验一