欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Mybatis的緩存

 更新時(shí)間:2021年01月16日 08:56:28   作者:Narule  
這篇文章主要介紹了Mybatis緩存的相關(guān)資料,幫助大家更好的理解和使用Mybatis框架,感興趣的朋友可以了解下

Mybatis的緩存

mybatis是一個查詢數(shù)據(jù)庫的封裝框架,主要是封裝提供靈活的增刪改sql,開發(fā)中,service層能夠通過mybatis組件查詢和修改數(shù)據(jù)庫中表的數(shù)據(jù);作為查詢工具,mybatis有使用緩存,這里講一下mybatis的緩存相關(guān)源碼。

緩存

在計(jì)算機(jī)里面,任何信息都有源頭,緩存一般指源頭信息讀取后,放在內(nèi)存或者其他讀取較快的地方,下次讀取相同信息不去源頭查詢而是直接從內(nèi)存(或者能快速存取的硬件)讀取。這樣可以減少硬件使用,提高讀取速度。

mybatis也是這樣,查詢數(shù)據(jù)庫的數(shù)據(jù)之后,mybatis可以把查詢結(jié)果緩存到內(nèi)存,下次查詢?nèi)绻樵冋Z句相同,并且查詢相關(guān)的表的數(shù)據(jù)沒被修改過,就可以直接返回緩存中的結(jié)果,而不用去查詢數(shù)據(jù)庫的語句,有效節(jié)省了時(shí)間。

簡單看一下mybatis一級緩存和二級緩存相關(guān)源碼,學(xué)習(xí)使用

一級緩存

通過查看源碼可知,一級緩存是綁定sqSsession中的,所以每次查詢sqlSession不同就失效,相同的sqlSession可以使用一級緩存。

mybatis默認(rèn)sqlsession:org.apache.ibatis.session.defaults.DefaultSqlSession

構(gòu)造方法中傳入executor(查詢執(zhí)行對象)

 public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
  this.configuration = configuration;
  this.executor = executor;
  this.dirty = false;
  this.autoCommit = autoCommit;
 }

executor中攜帶一級緩存成員:

 protected BaseExecutor(Configuration configuration, Transaction transaction) {
  this.transaction = transaction;
  this.deferredLoads = new ConcurrentLinkedQueue<>();
  this.localCache = new PerpetualCache("LocalCache"); //默認(rèn)一級緩存
  this.localOutputParameterCache = new PerpetualCache("LocalOutputParameterCache");
  this.closed = false;
  this.configuration = configuration;
  this.wrapper = this;
 }

查詢使用一級緩存邏輯

org.apache.ibatis.executor.BaseExecutor.query()

 public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
  ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
  
  List<E> list;
  try {
   queryStack++;
   	//localCache 一級緩存
   list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;
    //先從一級緩存中獲取,key是通過sql語句生成
   if (list != null) {
    handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
   } else {
    // 如果緩存中沒有 才從數(shù)據(jù)庫查詢
    list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
   }
  } finally {
   queryStack--;
  }
  return list;
 }

 //從數(shù)據(jù)庫讀取數(shù)據(jù)
 private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
  List<E> list;
  localCache.putObject(key, EXECUTION_PLACEHOLDER);
  try {
   list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
  } finally {
   localCache.removeObject(key);//將一級緩存清除
  }
  localCache.putObject(key, list);//返回查詢結(jié)果之前,先放入一級緩存 刷新
  if (ms.getStatementType() == StatementType.CALLABLE) {
   localOutputParameterCache.putObject(key, parameter);
  }
  return list;
 }

二級緩存

二級緩存mapper中的,默認(rèn)是開啟的,但需要在映射文件mapper.xml中添加<cache/>標(biāo)簽

<mapper namespace="userMapper">
	<cache/><!-- 添加cache標(biāo)簽表示此mapper使用二級緩存 -->
</mapper>

配置false可以關(guān)閉二級緩存

二級緩存的解析

org.apache.ibatis.builder.xml.XMLMapperBuilder

 private void configurationElement(XNode context) {
  try {
   //...
   cacheElement(context.evalNode("cache")); //解析cache標(biāo)簽
  } catch (Exception e) {
   throw new BuilderException("Error parsing Mapper XML. The XML location is '" + resource + "'. Cause: " + e, e);
  }
 }

 private void cacheElement(XNode context) {
  if (context != null) { // if hava cache tag 如果有cache標(biāo)簽才執(zhí)行下面的邏輯
   String type = context.getStringAttribute("type", "PERPETUAL");
   Class<? extends Cache> typeClass = typeAliasRegistry.resolveAlias(type);
   String eviction = context.getStringAttribute("eviction", "LRU");
   Class<? extends Cache> evictionClass = typeAliasRegistry.resolveAlias(eviction);
   Long flushInterval = context.getLongAttribute("flushInterval");
   Integer size = context.getIntAttribute("size");
   boolean readWrite = !context.getBooleanAttribute("readOnly", false);
   boolean blocking = context.getBooleanAttribute("blocking", false);
   Properties props = context.getChildrenAsProperties();
   builderAssistant.useNewCache(typeClass, evictionClass, flushInterval, size, readWrite, blocking, props);//建立二級緩存
  }
 }

org.apache.ibatis.builder.MapperBuilderAssistant.useNewCache():

 public Cache useNewCache(Class<? extends Cache> typeClass,
   Class<? extends Cache> evictionClass,
   Long flushInterval,
   Integer size,
   boolean readWrite,
   boolean blocking,
   Properties props) {
  Cache cache = new CacheBuilder(currentNamespace)
    .implementation(valueOrDefault(typeClass, PerpetualCache.class))
    .addDecorator(valueOrDefault(evictionClass, LruCache.class))
    .clearInterval(flushInterval)
    .size(size)
    .readWrite(readWrite)
    .blocking(blocking)
    .properties(props)
    .build();
  configuration.addCache(cache);//二級緩存賦值,如果cache標(biāo)簽為空,不會執(zhí)行此方法,currentCache為空
  currentCache = cache; 
  return cache;
 }

 在映射文件mapper中如果沒有cache標(biāo)簽,不會執(zhí)行上面的useNewCache方法,cache為null,就不會使用二級緩存(相當(dāng)于失效)。

查詢使用二級緩存邏輯

org.apache.ibatis.executor.CachingExecutor :

 @Override
 public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
   throws SQLException {
  Cache cache = ms.getCache(); 
  if (cache != null) {//如果二級緩存對象不為空 嘗試在二級緩存中獲?。]有cache標(biāo)簽此對象就是空)
   flushCacheIfRequired(ms);
   if (ms.isUseCache() && resultHandler == null) {
    ensureNoOutParams(ms, boundSql);
    @SuppressWarnings("unchecked")
    List<E> list = (List<E>) tcm.getObject(cache, key); //從二級緩存中獲取數(shù)據(jù)
    if (list == null) {
     list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); //如果為空,使用delegate查詢(BaseExecutor)
     tcm.putObject(cache, key, list); // 查詢結(jié)果保存到二級緩存
    }
    return list;
   }
  }
  return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
 }

二級緩存和一級緩存不用想,數(shù)據(jù)庫的數(shù)據(jù)被修改是要清空緩存的,不然數(shù)據(jù)有誤,至于怎么清空,是另一套邏輯了,mapper中的cache標(biāo)簽可以配置一些參數(shù),比如緩存定期清空。

一級二級緩存先后順序

mybatis默認(rèn)是先查詢二級緩存,沒有,再查看一級緩存,都為空,最后查詢數(shù)據(jù)庫

以上就是詳解Mybatis的緩存的詳細(xì)內(nèi)容,更多關(guān)于Mybatis的緩存的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring Boot實(shí)現(xiàn)圖片上傳功能

    Spring Boot實(shí)現(xiàn)圖片上傳功能

    這篇文章主要為大家詳細(xì)介紹了Spring Boot實(shí)現(xiàn)圖片上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 關(guān)于Java中的mysql時(shí)區(qū)問題詳解

    關(guān)于Java中的mysql時(shí)區(qū)問題詳解

    這篇文章主要給大家介紹了關(guān)于Java中mysql時(shí)區(qū)問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • springboot 自定義屬性與加載@value示例詳解

    springboot 自定義屬性與加載@value示例詳解

    在SpringBoot框架中,自定義屬性通常通過application.properties文件配置,并使用@Value注解加載,雖然這是一種可行的方法,但存在一種更優(yōu)雅的實(shí)現(xiàn)方式,本文給大家介紹springboot 自定義屬性與加載@value的相關(guān)操作,感興趣的朋友一起看看吧
    2024-10-10
  • springmvc參數(shù)為對象,數(shù)組的操作

    springmvc參數(shù)為對象,數(shù)組的操作

    這篇文章主要介紹了springmvc參數(shù)為對象,數(shù)組的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • IDEA插件之快速刪除Java代碼中的注釋

    IDEA插件之快速刪除Java代碼中的注釋

    這篇文章主要介紹了IDEA插件之快速刪除Java代碼中的注釋,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • idea配置maven環(huán)境時(shí)maven下載速度慢的解決方法

    idea配置maven環(huán)境時(shí)maven下載速度慢的解決方法

    我們在idea配置maven環(huán)境的時(shí)候會發(fā)現(xiàn)maven更新慢的現(xiàn)象,解決辦法就是下載國內(nèi)的鏡像包,完美解決下載速度慢的問題,文中有詳細(xì)的具體操作方法,并通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • 通過openOffice將office文件轉(zhuǎn)成pdf

    通過openOffice將office文件轉(zhuǎn)成pdf

    這篇文章主要介紹了通過openOffice將office文件轉(zhuǎn)成pdf,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • java有界類型參數(shù)的實(shí)例用法

    java有界類型參數(shù)的實(shí)例用法

    小編給大家整理了一篇關(guān)于java有界類型參數(shù)的使用的相關(guān)文章及擴(kuò)展實(shí)例內(nèi)容,有需要的朋友們可以學(xué)習(xí)參考下。
    2021-07-07
  • Java設(shè)計(jì)模式中的原型模式講解

    Java設(shè)計(jì)模式中的原型模式講解

    原型模式是用于創(chuàng)建重復(fù)的對象,同時(shí)又能保證性能。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式,今天通過本文給大家介紹下Java?原型設(shè)計(jì)模式,感興趣的朋友一起看看吧
    2023-04-04
  • Java數(shù)據(jù)結(jié)構(gòu)之有效隊(duì)列定義與用法示例

    Java數(shù)據(jù)結(jié)構(gòu)之有效隊(duì)列定義與用法示例

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之有效隊(duì)列定義與用法,結(jié)合實(shí)例形式分析了java有效隊(duì)列的數(shù)據(jù)插入、刪除、判斷、計(jì)算等相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10

最新評論