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

深入理解什么是Mybatis懶加載(延遲加載)

 更新時間:2023年10月27日 10:39:46   作者:秦懷  
這篇文章主要介紹了深入理解什么是Mybatis懶加載(延遲加載),mybatis的懶加載,也稱為延遲加載,是指在進行關(guān)聯(lián)查詢的時候,按照設(shè)置延遲規(guī)則推遲對關(guān)聯(lián)對象的select查詢,延遲加載可以有效的減少數(shù)據(jù)庫壓力,需要的朋友可以參考下

mybatis懶加載

mybatis的懶加載,也稱為延遲加載,是指在進行關(guān)聯(lián)查詢的時候,按照設(shè)置延遲規(guī)則推遲對關(guān)聯(lián)對象的select查詢,延遲加載可以有效的減少數(shù)據(jù)庫壓力。

延遲加載只對關(guān)聯(lián)對象有延遲設(shè)置,主加載對象都是直接執(zhí)行查詢語句的

關(guān)聯(lián)對象加載類型

mybatis的關(guān)聯(lián)對象的查詢select語句的執(zhí)行時機,可以分為3類,直接加載,侵入式加載與深度延遲加載。

1.直接加載

執(zhí)行完主加載對象的select語句,馬上就會執(zhí)行關(guān)聯(lián)對象的select語句。

2.侵入式延遲加載

執(zhí)行對主加載對象的查詢時,不會執(zhí)行關(guān)聯(lián)對象的查詢,但是當(dāng)訪問主加載對象的詳情時,就會馬上執(zhí)行關(guān)聯(lián)對象的select查詢,也就是說關(guān)聯(lián)對象的查詢執(zhí)行,侵入到了豬價在對象的詳情訪問中,可以理解為,將關(guān)聯(lián)對象的詳情侵入到主加載對象的詳情中,作為它的一部分出現(xiàn)了。

3.深度延遲加載

執(zhí)行對主加載對象的查詢的時候,不會執(zhí)行對關(guān)聯(lián)對象的查詢,訪問主加載對象的詳情的時候,也不會執(zhí)行關(guān)聯(lián)對象的select查詢,只有當(dāng)真正的訪問關(guān)聯(lián)對象的詳情的時候,才會執(zhí)行對關(guān)聯(lián)對象的select查詢。

注意:延遲加載的最基本要求,關(guān)聯(lián)對象的查詢與主加載對象的查詢必須是分別放在兩個語句中的,不能使用多表連接查詢,因為多表連接查詢相當(dāng)于把多張表連接成一張表的查詢,無法做到分開查詢,會一次性將表的內(nèi)容查詢出來。 延遲加載,可以應(yīng)用到一對多,一對一,多對一,多對多的關(guān)聯(lián)查詢中。

舉個例子:我們只用上一個demo,查詢minister與country之間的關(guān)系,數(shù)據(jù)庫如下:

#創(chuàng)建數(shù)據(jù)庫
CREATE DATABASE `test` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
#創(chuàng)建數(shù)據(jù)表
CREATE TABLE `test`.`student` ( `sid` INT(10) NOT NULL AUTO_INCREMENT ,`sname` VARCHAR(20) NOT NULL ,PRIMARY KEY(`sid`)) ENGINE = MyISAM;
CREATE TABLE `test`.`course` ( `cid` INT(10) NOT NULL AUTO_INCREMENT ,`cname` VARCHAR(20) NOT NULL ,PRIMARY KEY(`cid`)) ENGINE = MyISAM;
CREATE TABLE `test`.`middle` (
`id` INT(10) NOT NULL AUTO_INCREMENT ,`studentId` INT(10) NOT NULL ,`courseId` INT(10) NOT NULL ,PRIMARY KEY(`id`)) ENGINE = MyISAM;
#初始化數(shù)據(jù)表
INSERT INTO `course` (`cid`, `cname`) VALUES ('1', 'JAVA') ;
INSERT INTO `course` (`cid`, `cname`) VALUES ('2', 'C++') ;
INSERT INTO `course` (`cid`, `cname`) VALUES ('3', 'JS') ;

INSERT INTO `student` (`sid`, `sname`) VALUES ('1', 'Jam') ;
INSERT INTO `student` (`sid`, `sname`) VALUES ('2', 'Lina') ;

INSERT INTO `middle` (`id`, `studentId`, `courseId`) VALUES ('1', '1', '1');
INSERT INTO `middle` (`id`, `studentId`, `courseId`) VALUES ('2', '1', '2');
INSERT INTO `middle` (`id`, `studentId`, `courseId`) VALUES ('3', '2', '1');
INSERT INTO `middle` (`id`, `studentId`, `courseId`) VALUES ('4', '2', '3');

與之對應(yīng)的實體類:Country.class

public class Country {
	private Integer cid;
	private String cname;

	private Set<Minister> ministers;
	public Integer getCid() {
		return cid;
	}
	public void setCid(Integer cid) {
		this.cid = cid;
	}
	public String getName() {
		return cname;
	}
	public void setName(String cname) {
		this.cname = cname;
	}
	public Set<Minister> getMinisters() {
		return ministers;
	}
	public void setMinisters(Set<Minister> ministers) {
		this.ministers = ministers;
	}
	@Override
	public String toString() {
		return "Country [cid=" + cid + ", cname=" + cname + ", ministers="
				+ ministers + "]";
	}
}

Minister.class

public class Minister {
	private Integer mid;
	private String mname;
	@Override
	public String toString() {
		return "Minister [mid=" + mid + ", mname=" + mname + "]";
	}
	public Integer getMid() {
		return mid;
	}
	public void setMid(Integer mid) {
		this.mid = mid;
	}
	public String getMname() {
		return mname;
	}
	public void setMname(String mname) {
		this.mname = mname;
	}
	
}

主配置文件mybatis.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 配置數(shù)據(jù)庫文件 -->
    <properties resource="jdbc_mysql.properties">

    </properties>
    <settings>
        <setting name="lazyLoadingEnabled" value="false"/>
        <!--<setting name="aggressiveLazyLoading" value="false"/>-->
    </settings>
    <!-- 別名,對數(shù)據(jù)對象操作全名太長,需要使用別名 -->
    <typeAliases>
        <!--<typeAlias type="bean.Student" alias="Student"/>-->
        <!--直接使用類名即可,對于整個包的路徑配置(別名),簡單快捷 -->
        <package name="beans"/>
    </typeAliases>
    <!-- 配置運行環(huán)境 -->
    <!-- default 表示默認(rèn)使用哪一個環(huán)境,可以配置多個,比如開發(fā)時的測試環(huán)境,上線后的正式環(huán)境等 -->
    <environments default="mysqlEM">
        <environment id="mysqlEM">
            <transactionManager type="JDBC">
            </transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 注冊映射文件 -->
    <mappers>
        <mapper resource="mapper/mapper.xml"/>
    </mappers>
</configuration>

mapper.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.ICountryDao">
    <!-- 	resultMap 能解決字段和屬性不一樣的問題 -->
    <!-- 以后用得比較多 ,是因為可以使用延遲加載-->
    <!-- 嵌套查詢 -->
    <select id="selectMinisterByCountry" resultType="Minister">
	select mid,mname from minister where countryId=#{ooo}
	</select>
    <resultMap type="Country" id="countryMapper">
        <id column="cid" property="cid"/>
        <result column="cname" property="cname"/>
        <!-- country中有一個成員變量是ministers,它的泛型是Minister -->
        <collection property="ministers"
                    ofType="Minister"
                    select="selectMinisterByCountry"
                    column="cid">
        </collection>
    </resultMap>
    <select id="selectCountryById" resultMap="countryMapper">
		select cid,cname
		from country
		where
		cid=#{cid}
	</select>
</mapper>

與之對應(yīng)的sql接口:

public interface ICountryDao {
	Country selectCountryById(int cid);
}

使用到的工具類:

public class MyBatisUtils {
  private static SqlSessionFactory sqlSessionFactory;

  public static SqlSession getSqlSession() {
    InputStream is;
    try {
      is = Resources.getResourceAsStream("mybatis.xml");
      if (sqlSessionFactory == null) {
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
      }
      return sqlSessionFactory.openSession();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return null;
  }
}

直接加載查詢

關(guān)于懶加載的配置,我們只需要在mybatis.xml文件里面使用就可以了,懶加載有一個總開關(guān),lazyloadingEnabled,只要置為false就可以將延遲加載關(guān)掉,那就是直接加載查詢了。配置在與之間。

    <properties resource="jdbc_mysql.properties">
    </properties>
    <settings>
        <setting name="lazyLoadingEnabled" value="flase"/>
    </settings>
    <!-- 別名,對數(shù)據(jù)對象操作全名太長,需要使用別名 -->
    <typeAliases>
        <!--<typeAlias type="bean.Student" alias="Student"/>-->
        <!--直接使用類名即可,對于整個包的路徑配置(別名),簡單快捷 -->
        <package name="bean"/>
    </typeAliases>

當(dāng)單元測試是直接?xùn)薱ountry對象的時候:

	@Test
	public void TestselectCountryById(){
		Country country=dao.selectCountryById(1);
	}

結(jié)果是,我們可以看到兩條sql,除了查詢country之外,連同minister關(guān)聯(lián)對象也一起查詢了,這就是直接加載,簡單粗暴,不管是否使用,都會先將關(guān)聯(lián)查詢加載:

[service] 2018-07-17 09:59:00,796 - dao.ICountryDao.selectCountryById -491  [main] DEBUG dao.ICountryDao.selectCountryById  - ==>  Preparing: select cid,cname from country where cid=? 
[service] 2018-07-17 09:59:00,823 - dao.ICountryDao.selectCountryById -518  [main] DEBUG dao.ICountryDao.selectCountryById  - ==> Parameters: 1(Integer)
[service] 2018-07-17 09:59:00,838 - dao.ICountryDao.selectMinisterByCountry -533  [main] DEBUG dao.ICountryDao.selectMinisterByCountry  - ====>  Preparing: select mid,mname from minister where countryId=? 
[service] 2018-07-17 09:59:00,838 - dao.ICountryDao.selectMinisterByCountry -533  [main] DEBUG dao.ICountryDao.selectMinisterByCountry  - ====> Parameters: 1(Integer)
[service] 2018-07-17 09:59:00,849 - dao.ICountryDao.selectMinisterByCountry -544  [main] DEBUG dao.ICountryDao.selectMinisterByCountry  - <====      Total: 2
[service] 2018-07-17 09:59:00,850 - dao.ICountryDao.selectCountryById -545  [main] DEBUG dao.ICountryDao.selectCountryById  - <==      Total: 1

侵入式延遲加載

需要將延遲加載開關(guān)開啟(true),同時也需要將侵入式加載開關(guān)開啟(true)

    <settings>
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressivelazyLoading" value="true"/>
    </settings>

1.當(dāng)我們只查詢country的時候,只會執(zhí)行country的查詢,不會執(zhí)行關(guān)聯(lián)查詢minister:

	@Test
	public void TestselectCountryById(){
		Country country=dao.selectCountryById(1);
	}

結(jié)果如下,只有一條sql:

[service] 2018-07-17 14:30:55,471 - dao.ICountryDao.selectCountryById -902  [main] DEBUG dao.ICountryDao.selectCountryById  - ==>  Preparing: select cid,cname from country where cid=? 
[service] 2018-07-17 14:30:55,494 - dao.ICountryDao.selectCountryById -925  [main] DEBUG dao.ICountryDao.selectCountryById  - ==> Parameters: 1(Integer)
[service] 2018-07-17 14:30:55,590 - dao.ICountryDao.selectCountryById -1021 [main] DEBUG dao.ICountryDao.selectCountryById  - <==      Total: 1

當(dāng)我們查詢country的屬性,但是不是minister屬性的時候:

	@Test
	public void TestselectCountryById(){
		Country country=dao.selectCountryById(1);
		System.out.println(country.getCid());
	}

結(jié)果如下,會加載到關(guān)聯(lián)對象minister,這就是侵入式延遲加載:

[service] 2018-07-17 14:32:37,959 - dao.ICountryDao.selectCountryById -724  [main] DEBUG dao.ICountryDao.selectCountryById  - ==>  Preparing: select cid,cname from country where cid=? 
[service] 2018-07-17 14:32:37,979 - dao.ICountryDao.selectCountryById -744  [main] DEBUG dao.ICountryDao.selectCountryById  - ==> Parameters: 1(Integer)
[service] 2018-07-17 14:32:38,170 - dao.ICountryDao.selectCountryById -935  [main] DEBUG dao.ICountryDao.selectCountryById  - <==      Total: 1
[service] 2018-07-17 14:32:38,171 - dao.ICountryDao.selectMinisterByCountry -936  [main] DEBUG dao.ICountryDao.selectMinisterByCountry  - ==>  Preparing: select mid,mname from minister where countryId=? 
[service] 2018-07-17 14:32:38,171 - dao.ICountryDao.selectMinisterByCountry -936  [main] DEBUG dao.ICountryDao.selectMinisterByCountry  - ==> Parameters: 1(Integer)
[service] 2018-07-17 14:32:38,173 - dao.ICountryDao.selectMinisterByCountry -938  [main] DEBUG dao.ICountryDao.selectMinisterByCountry  - <==      Total: 2

深度延遲加載

需要將延遲加載開關(guān)開啟(true),同時需要將侵入式加載開關(guān)關(guān)閉(false)

    <settings>
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressivelazyLoading" value="false"/>
    </settings>

1.當(dāng)我們只查詢出country的時候,只會查詢country,而不會查詢minister: 單元測試代碼:

	@Test
	public void TestselectCountryById(){
		Country country=dao.selectCountryById(1);
	}

[service] 2018-07-17 14:20:38,608 - dao.ICountryDao.selectCountryById -1271 [main] DEBUG dao.ICountryDao.selectCountryById  - ==>  Preparing: select cid,cname from country where cid=? 
[service] 2018-07-17 14:20:38,631 - dao.ICountryDao.selectCountryById -1294 [main] DEBUG dao.ICountryDao.selectCountryById  - ==> Parameters: 1(Integer)
[service] 2018-07-17 14:20:38,980 - dao.ICountryDao.selectCountryById -1643 [main] DEBUG dao.ICountryDao.selectCountryById  - <==      Total: 1

2.當(dāng)我們訪問country的屬性的時候,也不會加載關(guān)聯(lián)查詢的minister:

	@Test
	public void TestselectCountryById(){
		Country country=dao.selectCountryById(1);
		System.out.println(country.getCid());
	}

結(jié)果同樣是:

[service] 2018-07-17 14:24:03,004 - org.apache.ibatis.transaction.jdbc.JdbcTransaction -686  [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction  - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@cb51256]
[service] 2018-07-17 14:24:03,030 - dao.ICountryDao.selectCountryById -712  [main] DEBUG dao.ICountryDao.selectCountryById  - ==>  Preparing: select cid,cname from country where cid=? 
[service] 2018-07-17 14:24:03,078 - dao.ICountryDao.selectCountryById -760  [main] DEBUG dao.ICountryDao.selectCountryById  - ==> Parameters: 1(Integer)
[service] 2018-07-17 14:24:03,160 - dao.ICountryDao.selectCountryById -842  [main] DEBUG dao.ICountryDao.selectCountryById  - <==      Total: 1

3.當(dāng)我們查詢country屬性minister的時候:

	@Test
	public void TestselectCountryById(){
		Country country=dao.selectCountryById(1);
		System.out.println(country.getMinisters());
	}

我們可以看到結(jié)果,執(zhí)行了minister的查詢:

[service] 2018-07-17 14:26:55,913 - dao.ICountryDao.selectCountryById -1540 [main] DEBUG dao.ICountryDao.selectCountryById  - ==>  Preparing: select cid,cname from country where cid=? 
[service] 2018-07-17 14:26:55,943 - dao.ICountryDao.selectCountryById -1570 [main] DEBUG dao.ICountryDao.selectCountryById  - ==> Parameters: 1(Integer)
[service] 2018-07-17 14:26:56,161 - dao.ICountryDao.selectCountryById -1788 [main] DEBUG dao.ICountryDao.selectCountryById  - <==      Total: 1
[service] 2018-07-17 14:26:56,162 - dao.ICountryDao.selectMinisterByCountry -1789 [main] DEBUG dao.ICountryDao.selectMinisterByCountry  - ==>  Preparing: select mid,mname from minister where countryId=? 
[service] 2018-07-17 14:26:56,163 - dao.ICountryDao.selectMinisterByCountry -1790 [main] DEBUG dao.ICountryDao.selectMinisterByCountry  - ==> Parameters: 1(Integer)
[service] 2018-07-17 14:26:56,168 - dao.ICountryDao.selectMinisterByCountry -1795 [main] DEBUG dao.ICountryDao.selectMinisterByCountry  - <==      Total: 2
[Minister [mid=2, mname=bbb], Minister [mid=1, mname=aaa]]

來個表格~

加載方式lazyLoadingEnabledaggressiveLazyLoading
直接加載必須是false,默認(rèn)是false不管是什么,只要lazyLoadingEnabled是false就是直接加載
侵入式延遲加載必須是true必須是true
深度延遲加載必須是true必須是false,默認(rèn)是false

到此這篇關(guān)于深入理解什么是Mybatis懶加載(延遲加載)的文章就介紹到這了,更多相關(guān)Mybatis懶加載(延遲加載)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java深入分析了解平衡二叉樹

    Java深入分析了解平衡二叉樹

    平衡二叉樹又被稱為AVL樹(有別于AVL算法),且具有以下性質(zhì):它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,并且左右兩個子樹都是一棵平衡二叉樹。本文將詳解介紹一下平衡二叉樹的原理與實現(xiàn),需要的可以參考一下
    2022-06-06
  • Android 資源 id詳解及的動態(tài)獲取

    Android 資源 id詳解及的動態(tài)獲取

    這篇文章主要介紹了Android 資源 id詳解及的動態(tài)獲取的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • Java中死鎖與活鎖的具體實現(xiàn)

    Java中死鎖與活鎖的具體實現(xiàn)

    鎖發(fā)生在不同的請求中,本文主要介紹了Java中死鎖與活鎖,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 淺談Java抽象類和接口的個人理解

    淺談Java抽象類和接口的個人理解

    這篇文章主要介紹了淺談Java抽象類和接口的個人理解,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • SpringBoot實體多層嵌套判空字段的方式

    SpringBoot實體多層嵌套判空字段的方式

    這篇文章主要介紹了SpringBoot實體多層嵌套如何判空字段,最近在公司了接了個需求:需要開發(fā)一個中間系統(tǒng),進行三方聯(lián)調(diào),文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2024-09-09
  • Java虛擬機GC日志分析

    Java虛擬機GC日志分析

    這篇文章主要介紹了Java虛擬機GC日志分析,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • 如何在Spring Boot 項目中自定義 Validation 注解

    如何在Spring Boot 項目中自定義 Validation 注解

    本文詳解SpringBoot自定義Validation注解實現(xiàn)流程,包括定義注解、編寫校驗邏輯、應(yīng)用注解及異常處理,支持多地區(qū)手機號格式校驗和復(fù)雜業(yè)務(wù)規(guī)則,提升數(shù)據(jù)合法性校驗?zāi)芰?適用于微服務(wù)架構(gòu)參數(shù)校驗實踐,感興趣的朋友一起看看吧
    2025-07-07
  • springboot整合couchbase集群的步驟

    springboot整合couchbase集群的步驟

    couchbase是一款開源的,分布式的nosql數(shù)據(jù)庫,主要用于分布式緩存和數(shù)據(jù)存儲領(lǐng)域,本文給大家介紹springboot整合couchbase集群的步驟,感興趣的朋友一起看看吧
    2025-03-03
  • springboot項目以jar包運行的操作方法

    springboot項目以jar包運行的操作方法

    公司一個springboot項目本來是打war包的,突然要改為打jar包,不知所措了,糾結(jié)該如何操作呢,折騰半天終于搞定了,下面把解決方案分享給大家,對springboot打jar包方式感興趣的朋友一起看看吧
    2021-06-06
  • SpringBoot整合JPA的實例代碼

    SpringBoot整合JPA的實例代碼

    本篇文章主要介紹了SpringBoot整合JPA的實例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05

最新評論

新龙县| 弋阳县| 介休市| 礼泉县| 华阴市| 当雄县| 平远县| 渝中区| 建德市| 株洲县| 鄂伦春自治旗| 江门市| 峨眉山市| 富阳市| 嵊州市| 嘉祥县| 大英县| 崇阳县| 沾益县| 清丰县| 忻城县| 德兴市| 霍林郭勒市| 五大连池市| 沛县| 原平市| 嘉义县| 大兴区| 兴义市| 齐齐哈尔市| 平定县| 鹿邑县| 山阴县| 新宁县| 永泰县| 达孜县| 平定县| 贞丰县| 涞源县| 平武县| 深水埗区|