亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Mybatis延遲加載和緩存深入講解

 更新時間:2019年02月11日 09:58:27   作者:風沙迷了眼  
這篇文章主要給大家介紹了關(guān)于Mybatis延遲加載和緩存的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面來一起學(xué)習學(xué)習吧

一、Mybatis中的延遲加載

1、延遲加載背景:Mybatis中Mapper配置文件中的resultMap可以實現(xiàn)高級映射(使用association、collection實現(xiàn)一對一及一對多(多對多)映射),同樣的association、collection具備延遲加載功能。所謂延遲加載,就是先單表查詢,需要時再從關(guān)聯(lián)表去關(guān)聯(lián)查詢(同樣也可能只是是單表查詢),大大單表查詢速度更快,所以可以間接的提高數(shù)據(jù)庫性能

2、在mybatis核心配置文件中配置,其中l(wèi)azyLoadingEnabled表示懶加載開關(guān)、aggressiveLazyLoading表示非懶加載(積極加載),通過在Mybatis核心配置文件中配置這些屬性的值來使用Mybatis的懶加載,具體配置方式如下:

 <settings>
  <!--懶加載模式在Mybatis中默認是關(guān)閉的-->
  <setting name="lazyLoadingEnabled" value="true"/>
  <!--不同于懶加載的:積極加載方式,所以在懶加載的時候設(shè)置該屬性為false-->
  <setting name="aggressiveLazyLoading" value="false"></setting>
 </settings>

3、由于是使用懶加載,所以我們顯然可以將Mapper配置文件中的查詢分為兩張單表查詢的statment,其中User表的查詢放在Order查詢配置的resultMap中,并進行延遲加載的設(shè)置

<select id="findUserByUid" parameterType="int" resultType="cn.mybatis.po.User">
  SELECT * FROM USER WHERE uid = #{id}
 </select>

 <resultMap id="OrderAndUserByLazyLoading" type="cn.mybatis.po.Order">
  <id column="oid" property="oid"></id>
  <result column="total" property="total"></result>
  <result column="ordertime" property="ordertime"></result>
  <result column="name" property="name"></result>

  <!--
   實現(xiàn)延遲加載功能
   select:指定延遲加載需要執(zhí)行的statment的id(即根據(jù)用戶id查詢用戶信息的select的statment)
   column:關(guān)聯(lián)查詢的列信息-->
  <association property="user" javaType="cn.mybatis.po.User" select="findUserByUid" column="uid">
  </association>
 </resultMap>
 
 <select id="findOrderAndUserByLazyLoading" resultMap="OrderAndUserByLazyLoading">
  SELECT * FROM orders
 </select>

LazyLoading配置文件信息

4、在Mapper.java中添加了延遲加載的測試方法

 //延遲加載測試方法
 public List<Order> findOrderAndUserByLazyLoading() throws Exception;

5、使用Junit測試延遲加載的測試代碼

@Test
 public void testFindOrderAndUserByLazyLoading() throws Exception {
  SqlSession sqlSession = sqlSessionFactory.openSession();
  OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);

  List<Order> orderList= orderMapper.findOrderAndUserByLazyLoading();

  for (Order order : orderList) {
   System.out.println(order.getUser());
  }

  sqlSession.close();
 }

6、測試結(jié)果,從測試結(jié)果可以看出,我們首先只是單表查詢了order是表的信息,然后在遍歷查詢到的結(jié)果(打印User信息)的時候,又發(fā)出查詢user信息的Sql,從而實現(xiàn)了延遲加載的功能

二、Mybatis中的一級緩存

1、一級緩存是在SqlSession 層面進行緩存的。即在同一個SqlSession 中,多次調(diào)用同一個Mapper中的同一個statment并且是同一個參數(shù)的話,只會進行一次數(shù)據(jù)庫查詢,然后把數(shù)據(jù)緩存到緩沖中,如果以后要查詢相同的Sql和參數(shù),就直接先從緩存中取出數(shù)據(jù),不會直接去查數(shù)據(jù)庫。​ 但是不同的SqlSession對象,因為不用的SqlSession都是相互隔離的,所以相同的Mapper、參數(shù)和方法,他還是會再次發(fā)送到SQL到數(shù)據(jù)庫去執(zhí)行,返回結(jié)果。(本質(zhì)上是在SqlSession作用域下面的HashMap本地緩存,當 SqlSession 刷新或關(guān)閉之后,該Session中的所有 緩存數(shù)據(jù)就將清空。)可以用下面的這張圖來表示一級緩存

2、我們來使用一級緩存進行測試,首先通過上面一級緩存的簡單定義,我們可以得到下面的這張簡略圖,用以示解一級緩存。在實例圖中,第一次查詢某條記錄時候,Mybatis所做的就是將查詢到的結(jié)果放在該SqlSession的緩存中,如果期間沒有該數(shù)據(jù)的修改、刪除、或者增加操作,那么之后再讀取該數(shù)據(jù)就會直接從緩存中得到數(shù)據(jù),而不用再向數(shù)據(jù)庫發(fā)Sql請求,當然,如果第一次查詢之后,對數(shù)據(jù)進行了delete、update、insert操作,那么就會刪除緩存中的數(shù)據(jù),這樣做的目的也很顯然,保證數(shù)據(jù)的最新性,避免出現(xiàn)臟讀的情況。

3、一級緩存的測試(Mybatis中默認開啟的是一級緩存)

做個簡單的測試:按照上面的圖中所示,我們查詢兩次id=1的User信息,并且兩次查詢期間沒有進行會清空緩存的操作,結(jié)果應(yīng)該是只向數(shù)據(jù)庫發(fā)送一次Sql查詢

@Test
 public void testUpdateUserInfo() throws Exception {
  SqlSession sqlSession = sqlSessionFactory.openSession();
  UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

  User user1 = userMapper.findUserById(1);
  System.out.println(user1);

  User user2 = userMapper.findUserById(1);
  System.out.println(user2);

  sqlSession.close();
 }

4、我們通過觀察日志可以看出,只是在第一次查詢的時候發(fā)送了Sql,第二次是直接打印user信息

當然,接下來要做的測試就是在兩次查詢期間做insert操作,然后觀察日志,結(jié)果應(yīng)該是發(fā)現(xiàn)會想數(shù)據(jù)庫發(fā)送兩次sql

@Test
 public void testUpdateUserInfo() throws Exception {
  SqlSession sqlSession = sqlSessionFactory.openSession();
  UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

  User user1 = userMapper.findUserById(1);
  System.out.println(user1);

  User user = new User("InsertTest","insert","insert","man");
  userMapper.insertUserInfo(user);
  sqlSession.commit();

  User user2 = userMapper.findUserById(1);
  System.out.println(user2);

  sqlSession.close();
 }

5、我們在測試代碼中加了insert之后,通過觀察日志可以發(fā)現(xiàn),在查詢過程中,向Database發(fā)送了兩條select語句,可以驗證上面的猜想

三、Mybatis中的二級緩存

1、二級緩存的實現(xiàn)機制基本上和一級緩存機制相同,不同的作用域不一樣,二級緩存區(qū)域在一個個的mapper中。顯然,由于多個SqlSession可以操作同一個mapper,所以二級緩存比一級緩存域更大。二級緩存按照mapper劃分,簡而言之,也可說成按照mapper中的namespace進行劃分,這樣看來,每一個namespace下面都有一個二級緩存區(qū)域,而如果兩個mapper的namespace相同,那么數(shù)據(jù)會緩存在相同的緩存區(qū)域中。當然,類似于一級緩存的特點,如果不同的SqlSession進行數(shù)據(jù)的insert、delete、update操作的話,也會清空二級緩存中的數(shù)據(jù)

2、開啟二級緩存后,進行測試。具體使用二級緩存在配置文件中的配置為:

首先在Mybatis的核心配置文件中配置二級緩存(本項目中的SQLMapConfig.xml)

 <!--settings配置二級緩存 -->
 <settings>
  <setting name="cacheEnabled" value="true"></setting>
 </settings>

然后在需要配置二級緩存的特定mapper配置文件中進行添加二級緩存的配置

3、編寫測試程序并運行

@Test
 public void testCache() throws Exception {
  SqlSession sqlSession1 = sqlSessionFactory.openSession();
  UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
  User user1 = userMapper1.findUserById(1);
  System.out.println(user1);
  //需要將SqlSession關(guān)閉才能將數(shù)據(jù)寫入緩存
  sqlSession1.close();


  SqlSession sqlSession2 = sqlSessionFactory.openSession();
  UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
  User user2 = userMapper2.findUserById(1);
  System.out.println(user2);
  sqlSession2.close();
 }

在運行的時候出現(xiàn)了下面的異常,原因就是沒有實現(xiàn)序列化接口,由于緩存數(shù)據(jù)可能再本地內(nèi)存中,也可能在其他存儲介質(zhì)上,所以存在對象的序列化和反序列化

所以在實現(xiàn)序列化接口之后,再次運行,得到下面的結(jié)果

四、Mybatis和ehcache整合

1、首先說明ehcache是一個分布式的緩存框架,而使用Mybatis和ehcache進行整合的時候,首先就需要導(dǎo)入ehcache的jar包和mybatis與ehcache整合的jar包,如下圖所示

2、下面是mybatis-ehcache整合jar包中的Cache接口實現(xiàn)類

3、然后我們在Mapper配置文件中配置二級緩存

 <!--關(guān)于cache標簽的一些屬性說明:
  type:指定Mybatis中默認實現(xiàn)的cache接口的實現(xiàn)類類型,Mybatis中默認使用PerpetualCache
  如果和ehcache整合,需要將type配置為ehcache實現(xiàn)cache的實現(xiàn)類類型
 -->
 <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

4、下面是mybatis和ehcache整合之后的測試結(jié)果

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • Spring boot將配置屬性注入到bean類中

    Spring boot將配置屬性注入到bean類中

    本篇文章主要介紹了Spring boot將配置屬性注入到bean類中,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • Java設(shè)計模式七大原則之開閉原則詳解

    Java設(shè)計模式七大原則之開閉原則詳解

    開閉原則,又稱為OCP原則,即一個軟件實體如類,模塊和函數(shù)應(yīng)該對擴展開放,對修改關(guān)閉。本文將詳細介紹Java設(shè)計模式七大原則之一的開閉原則,需要的可以參考一下
    2022-02-02
  • Netty啟動步驟綁定端口示例方法源碼分析

    Netty啟動步驟綁定端口示例方法源碼分析

    這篇文章主要介紹了Netty啟動步驟綁定端口源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-03-03
  • Java選擇結(jié)構(gòu)與循環(huán)結(jié)構(gòu)的使用詳解

    Java選擇結(jié)構(gòu)與循環(huán)結(jié)構(gòu)的使用詳解

    循環(huán)結(jié)構(gòu)是指在程序中需要反復(fù)執(zhí)行某個功能而設(shè)置的一種程序結(jié)構(gòu)。它由循環(huán)體中的條件,判斷繼續(xù)執(zhí)行某個功能還是退出循環(huán),選擇結(jié)構(gòu)用于判斷給定的條件,根據(jù)判斷的結(jié)果判斷某些條件,根據(jù)判斷的結(jié)果來控制程序的流程
    2022-03-03
  • hadoop?全面解讀自定義分區(qū)

    hadoop?全面解讀自定義分區(qū)

    Hadoop是一個由Apache基金會所開發(fā)的分布式系統(tǒng)基礎(chǔ)架構(gòu)。用戶可以在不了解分布式底層細節(jié)的情況下,開發(fā)分布式程序。充分利用集群的威力進行高速運算和存儲
    2022-02-02
  • mybatis之批量添加問題

    mybatis之批量添加問題

    這篇文章主要介紹了mybatis之批量添加問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • dubbo如何實現(xiàn)consumer從多個group中調(diào)用指定group的provider

    dubbo如何實現(xiàn)consumer從多個group中調(diào)用指定group的provider

    這篇文章主要介紹了dubbo如何實現(xiàn)consumer從多個group中調(diào)用指定group的provider問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Spring中的@Cacheable緩存注解詳解

    Spring中的@Cacheable緩存注解詳解

    這篇文章主要介紹了Spring中的@Cacheable緩存注解詳解,數(shù)據(jù)庫查找的流程是先要從磁盤拿到數(shù)據(jù),再刷新到內(nèi)存,再返回數(shù)據(jù)。磁盤相比于內(nèi)存來說,速度是很慢的,為了提升性能,就出現(xiàn)了基于內(nèi)存的緩存,需要的朋友可以參考下
    2023-05-05
  • jackson設(shè)置返回null為空字符串的操作

    jackson設(shè)置返回null為空字符串的操作

    這篇文章主要介紹了jackson設(shè)置返回null為空字符串的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Java中equals()方法實例詳解

    Java中equals()方法實例詳解

    equals方法是java.lang.Object類的方法,下面這篇文章主要給大家介紹了關(guān)于Java中equals()方法的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-12-12

最新評論