最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mybatis 一級(jí)緩存與二級(jí)緩存的實(shí)現(xiàn)

 更新時(shí)間:2021年05月24日 09:37:33   作者:whhwch1986  
mybatis作為一個(gè)流行的持久化工具,緩存必然是缺少不了的組件。通過(guò)這篇文章,就讓我們來(lái)了解一下一級(jí)緩存與二級(jí)緩存的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

mybatis緩存

mybatis作為一個(gè)流行的持久化工具,緩存必然是缺少不了的組件。通過(guò)這篇文章,就讓我們來(lái)了解一下mybatis的緩存。

mybatis緩存類(lèi)型

說(shuō)起mybatis的緩存,了解過(guò)的同學(xué)都知道,mybatis中可以有兩種緩存類(lèi)型:

  • 第一種,我們通常稱(chēng)為以及緩存,或者sqlSession級(jí)別的緩存,這種緩存是mybatis自帶的,如果mapper中的配置都是默認(rèn)的話(huà),那么一級(jí)緩存也是默認(rèn)開(kāi)啟的。
  • 第二種,就是非sqlSession級(jí)別的緩存了,我們通常稱(chēng)為二級(jí)緩存,mybatis中的二級(jí)緩存需要實(shí)現(xiàn)Cache接口,并且配置在mapper中,要先開(kāi)啟的話(huà),需要一些配置,下面我們會(huì)詳細(xì)說(shuō)到。

一級(jí)緩存

作為mybatis自帶的緩存,我們通過(guò)代碼來(lái)分析一下其原理。
首先,我們來(lái)看下一級(jí)緩存的效果。
測(cè)試代碼:

@Test
public void test_Cache() throws Exception {
    InputStream input = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(input);
    SqlSession sqlSession = factory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    System.out.println("the first query : ");
    mapper.queryAllUsers();
    System.out.println("====================================");
    System.out.println("the second query : ");
    mapper.queryAllUsers();
    sqlSession.commit();
}

mapper配置如下,我們采用默認(rèn)配置:

<select id="queryAllUsers" resultType="User">
    select * from hwc_users
</select>

運(yùn)行結(jié)果如下:

Created connection 1191654595.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@470734c3]
==> Preparing: select * from hwc_users
==> Parameters:
<== Columns: id, name, age, email
<== Row: 1, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 2, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 3, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 4, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 5, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 6, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 7, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 8, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 9, 胡文超, 35, huwenchao@cheryfs.cn
<== Total: 9
====================================
the second query :
Cache Hit Ratio [com.huwc.mapper.UserMapper]: 0.0

Process finished with exit code 0

從上述結(jié)果可以看到,第二次查詢(xún)并沒(méi)有從數(shù)據(jù)庫(kù)獲取,并且沒(méi)有從二級(jí)緩存中獲取,由此可見(jiàn),默認(rèn)配置情況下,同一個(gè)sqlSession中會(huì)默認(rèn)使用mybatis的一級(jí)緩存。

下面,我們從mybatis源碼來(lái)看一下:

在這里插入圖片描述

從上面的代碼中,我們可以看到:一級(jí)緩存是在BaseExecutor中命中的,BaseExecutor中的localCache屬性應(yīng)該就是用來(lái)存儲(chǔ)查詢(xún)結(jié)果的。

localCache的定義代碼如下:

在這里插入圖片描述

在這里插入圖片描述

從上述代碼可以看出:

BaseExecutor中集成了一級(jí)緩存,一級(jí)緩存為PerpetualCache(永久緩存?)的對(duì)象,其也是實(shí)現(xiàn)了Cache接口的對(duì)象,并且其存儲(chǔ)結(jié)果就是簡(jiǎn)單的HashMap。
并且從代碼上來(lái)看,一級(jí)緩存是無(wú)法禁止的。但是如果一個(gè)查詢(xún),我們就是不想讓其從緩存中獲取,必須從數(shù)據(jù)庫(kù)查詢(xún),那我們豈不是無(wú)法處理了?
答案必然是否定的,我們從代碼中可以看到:雖然一級(jí)緩存無(wú)法跳過(guò),但是我們可以將緩存中數(shù)據(jù)進(jìn)行清除處理,這樣一級(jí)緩存中就獲取不到結(jié)果集了:

在這里插入圖片描述

如何讓mybatis每次查詢(xún)都flush緩存結(jié)果集呢?答案是通過(guò)mapper配置中的flushCache屬性來(lái)處理:

<select id="queryAllUsers" resultType="User" flushCache="true">
    select * from hwc_users
</select>

加上這個(gè)屬性后,我們來(lái)看下程序執(zhí)行結(jié)果:

Created connection 1191654595.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@470734c3]
==> Preparing: select * from hwc_users
==> Parameters:
<== Columns: id, name, age, email
<== Row: 1, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 2, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 3, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 4, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 5, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 6, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 7, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 8, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 9, 胡文超, 35, huwenchao@cheryfs.cn
<== Total: 9
====================================
the second query :
Cache Hit Ratio [com.huwc.mapper.UserMapper]: 0.0
==> Preparing: select * from hwc_users
==> Parameters:
<== Columns: id, name, age, email
<== Row: 1, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 2, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 3, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 4, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 5, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 6, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 7, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 8, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 9, 胡文超, 35, huwenchao@cheryfs.cn
<== Total: 9

Process finished with exit code 0

可以看到,第二次查詢(xún)也檢索了數(shù)據(jù)庫(kù)來(lái)獲取結(jié)果。
一級(jí)緩存就說(shuō)到這里吧,下面我們來(lái)看看二級(jí)緩存。

二級(jí)緩存

mybatis的二級(jí)緩存是需要借助第三方的緩存來(lái)實(shí)現(xiàn),常用的有ehcache或者redis,其存儲(chǔ)類(lèi)型不同,但是在mybatis中的使用方式是一樣的,簡(jiǎn)單處理,我們使用ehcache來(lái)說(shuō)明。
通常來(lái)說(shuō),在mybatis中啟用二級(jí)緩存,我們需要以下的步驟:

1、在項(xiàng)目中引入ehcache模塊和mybatis-ehcache模塊

2、在項(xiàng)目中加如ehcache配置文件

3、在mybatis配置文件中我們需要在setting中配置cacheEnabled屬性;

4、在mapper配置文件中配置cache屬性,并指定緩存的實(shí)現(xiàn)類(lèi);

5、在statement中配置useCache屬性為”true“

第一步:首先我們?cè)陧?xiàng)目中引入相關(guān)模塊:

<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.10.0</version>
</dependency>
<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.2.1</version>
</dependency>

第二步:我們從網(wǎng)上抄一個(gè)ehcache的配置文件:ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">
    <diskStore path="java.io.tmpdir"/>
    <defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="false" diskPersistent="false"
                  timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/>
</ehcache>

第三步:配置mybatis屬性

<setting name="cacheEnabled" value="true"/>

之前,我們說(shuō)過(guò),mybatis的配置,主要是為了初始化Configuration對(duì)象,從Configuration代碼中我們看到,對(duì)應(yīng)的屬性默認(rèn)值就是為true,因此,此步驟也可以跳過(guò),直接采用mybatis的默認(rèn)值:

在這里插入圖片描述

第四步:配置mapper中的緩存屬性:

<mapper namespace="com.huwc.mapper.UserMapper">
    <cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
    ......
</mapper>

第五步:在statement中開(kāi)啟二級(jí)緩存:

<select id="queryAllUsers" resultType="User" useCache="true">
    select * from hwc_users
</select>

測(cè)試代碼如下,為了屏蔽一級(jí)緩存,我們?cè)诘谝淮尾樵?xún)和第二次查詢(xún)中將sqlSession進(jìn)行關(guān)閉并重新open:

@Test
public void test_Cache() throws Exception {
    InputStream input = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(input);
    SqlSession sqlSession = factory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    System.out.println("the first query : ");
    mapper.queryAllUsers();
    sqlSession.close();
    sqlSession = factory.openSession();
    mapper = sqlSession.getMapper(UserMapper.class);
    System.out.println("====================================");
    System.out.println("the second query : ");
    mapper.queryAllUsers();
    sqlSession.commit();
}

執(zhí)行結(jié)果如下:

Created connection 1191654595.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@470734c3]
==> Preparing: select * from hwc_users
==> Parameters:
<== Columns: id, name, age, email
<== Row: 1, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 2, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 3, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 4, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 5, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 6, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 7, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 8, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 9, 胡文超, 35, huwenchao@cheryfs.cn
<== Total: 9
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@470734c3]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@470734c3]
Returned connection 1191654595 to pool.
====================================
the second query :
Cache Hit Ratio [com.huwc.mapper.UserMapper]: 0.5

Process finished with exit code 0

從結(jié)果中,我們可以看到,二級(jí)緩存起到了作用,并且命中率為0.5(查詢(xún)兩次,一次命中)

下面,我們從mybatis的代碼來(lái)看下二級(jí)緩存使用:

在這里插入圖片描述

代碼截圖中,我們看到,二級(jí)緩存是在CacheExecutor中進(jìn)行的調(diào)用,并且最終使用的就是我們的Ehcache:

在這里插入圖片描述

并且,如果我們?cè)趍apper中的statement中也配置了flushCache,那么二級(jí)緩存也將在查詢(xún)前被清除掉,我們通過(guò)測(cè)試來(lái)看以下:

<select id="queryAllUsers" resultType="User" flushCache="true" useCache="true">
    select * from hwc_users
</select>

執(zhí)行結(jié)果如下:

Created connection 1191654595.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@470734c3]
==> Preparing: select * from hwc_users
==> Parameters:
<== Columns: id, name, age, email
<== Row: 1, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 2, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 3, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 4, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 5, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 6, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 7, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 8, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 9, 胡文超, 35, huwenchao@cheryfs.cn
<== Total: 9
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@470734c3]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@470734c3]
Returned connection 1191654595 to pool.
====================================
the second query :
Cache Hit Ratio [com.huwc.mapper.UserMapper]: 0.5
Opening JDBC Connection
Checked out connection 1191654595 from pool.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@470734c3]
==> Preparing: select * from hwc_users
==> Parameters:
<== Columns: id, name, age, email
<== Row: 1, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 2, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 3, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 4, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 5, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 6, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 7, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 8, 胡文超, 35, huwenchao@cheryfs.cn
<== Row: 9, 胡文超, 35, huwenchao@cheryfs.cn
<== Total: 9

Process finished with exit code 0

總結(jié):

1、mybatis的緩存處理,都交由Executor來(lái)處理,一級(jí)緩存是由BaseExecutor處理,二級(jí)緩存則由CacheExecutor處理;

2、statement中如果配置了flushCache為true,那么不論是一級(jí)緩存還是二級(jí)緩存都會(huì)失效;

3、要啟用二級(jí)緩存,需要在statement中配置useCache為true。

到此這篇關(guān)于Mybatis 一級(jí)緩存與二級(jí)緩存的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Mybatis 一級(jí)緩存與二級(jí)緩存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java swing實(shí)現(xiàn)電影購(gòu)票系統(tǒng)

    java swing實(shí)現(xiàn)電影購(gòu)票系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java swing實(shí)現(xiàn)電影購(gòu)票系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • Java如何執(zhí)行cmd命令

    Java如何執(zhí)行cmd命令

    這篇文章主要介紹了Java如何執(zhí)行cmd命令問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • Java web實(shí)現(xiàn)賬號(hào)單一登錄,防止同一賬號(hào)重復(fù)登錄(踢人效果)

    Java web實(shí)現(xiàn)賬號(hào)單一登錄,防止同一賬號(hào)重復(fù)登錄(踢人效果)

    這篇文章主要介紹了Java web實(shí)現(xiàn)賬號(hào)單一登錄,防止同一賬號(hào)重復(fù)登錄,有點(diǎn)類(lèi)似于qq登錄踢人效果,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-10-10
  • 最新評(píng)論

    屏东市| 浠水县| 明溪县| 新民市| 滕州市| 天津市| 泗洪县| 鱼台县| 高安市| 正宁县| 湖州市| 汪清县| 逊克县| 三明市| 上犹县| 南投县| 昭平县| 长兴县| 昭苏县| 织金县| 凌源市| 张家界市| 张掖市| 台南县| 威信县| 南和县| 海安县| 永清县| 徐汇区| 谢通门县| 新营市| 新巴尔虎左旗| 聂荣县| 张家港市| 康乐县| 涟水县| 红河县| 山东省| 海丰县| 察隅县| 罗源县|