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

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

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

mybatis懶加載

mybatis的懶加載,也稱為延遲加載,是指在進(jìn)行關(guān)聯(lián)查詢的時(shí)候,按照設(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í)行時(shí)機(jī),可以分為3類,直接加載,侵入式加載與深度延遲加載。

1.直接加載

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

2.侵入式延遲加載

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

3.深度延遲加載

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

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

舉個(gè)例子:我們只用上一個(gè)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)的實(shí)體類: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"/>-->
        <!--直接使用類名即可,對于整個(gè)包的路徑配置(別名),簡單快捷 -->
        <package name="beans"/>
    </typeAliases>
    <!-- 配置運(yùn)行環(huán)境 -->
    <!-- default 表示默認(rèn)使用哪一個(gè)環(huán)境,可以配置多個(gè),比如開發(fā)時(shí)的測試環(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 能解決字段和屬性不一樣的問題 -->
    <!-- 以后用得比較多 ,是因?yàn)榭梢允褂醚舆t加載-->
    <!-- 嵌套查詢 -->
    <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中有一個(gè)成員變量是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文件里面使用就可以了,懶加載有一個(gè)總開關(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"/>-->
        <!--直接使用類名即可,對于整個(gè)包的路徑配置(別名),簡單快捷 -->
        <package name="bean"/>
    </typeAliases>

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

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

結(jié)果是,我們可以看到兩條sql,除了查詢country之外,連同minister關(guān)聯(lián)對象也一起查詢了,這就是直接加載,簡單粗暴,不管是否使用,都會(huì)先將關(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),同時(shí)也需要將侵入式加載開關(guān)開啟(true)

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

1.當(dāng)我們只查詢country的時(shí)候,只會(huì)執(zhí)行country的查詢,不會(huì)執(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屬性的時(shí)候:

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

結(jié)果如下,會(huì)加載到關(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),同時(shí)需要將侵入式加載開關(guān)關(guān)閉(false)

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

1.當(dāng)我們只查詢出country的時(shí)候,只會(huì)查詢country,而不會(huì)查詢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的屬性的時(shí)候,也不會(huì)加載關(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的時(shí)候:

	@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]]

來個(gè)表格~

加載方式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中ConcurrentHashMap和Hashtable的區(qū)別

    Java中ConcurrentHashMap和Hashtable的區(qū)別

    ConcurrentHashMap?和?Hashtable?都是用于在Java中實(shí)現(xiàn)線程安全的哈希表數(shù)據(jù)結(jié)構(gòu)的類,但它們有很多區(qū)別,本文就來詳細(xì)的介紹一下,感興趣的可以了解一下
    2023-10-10
  • tk.mybatis通用插件updateByPrimaryKeySelective無法自動(dòng)更新列的解決辦法

    tk.mybatis通用插件updateByPrimaryKeySelective無法自動(dòng)更新列的解決辦法

    tk.mybatis是一個(gè)很好用的通用插件,本文主要介紹了tk.mybatis通用插件updateByPrimaryKeySelective無法自動(dòng)更新列的解決辦法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Java中基于maven實(shí)現(xiàn)zxing二維碼功能

    Java中基于maven實(shí)現(xiàn)zxing二維碼功能

    這篇文章主要介紹了Java中基于maven實(shí)現(xiàn)zxing二維碼功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-02-02
  • 通過jxl.jar 讀取、導(dǎo)出excel的實(shí)例代碼

    通過jxl.jar 讀取、導(dǎo)出excel的實(shí)例代碼

    通過jxl.jar 讀取、導(dǎo)出excel的實(shí)例代碼,需要的朋友可以參考一下
    2013-03-03
  • Kotlin協(xié)程與并發(fā)深入全面講解

    Kotlin協(xié)程與并發(fā)深入全面講解

    Android官方對協(xié)程的定義-協(xié)程是一種并發(fā)設(shè)計(jì)模式,您可以在Android平臺(tái)上使用它來簡化異步執(zhí)行的代碼。協(xié)程是在版本1.3中添加到Kotlin的,它基于來自其他語言的既定概念
    2022-11-11
  • 在Spring Boot中如何使用Cookies詳析

    在Spring Boot中如何使用Cookies詳析

    這篇文章主要給大家介紹了關(guān)于在Spring Boot中如何使用Cookies的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Java Swagger技術(shù)使用指南

    Java Swagger技術(shù)使用指南

    Swagger 是一個(gè)規(guī)范和完整的框架,用于生成、描述、調(diào)用和可視化 RESTful 風(fēng)格的 Web 服務(wù)??傮w目標(biāo)是使客戶端和文件系統(tǒng)作為服務(wù)器以同樣的速度來更新。文件的方法,參數(shù)和模型緊密集成到服務(wù)器端的代碼,允許API來始終保持同步
    2021-09-09
  • Mybatis中使用in()查詢的方式詳解

    Mybatis中使用in()查詢的方式詳解

    當(dāng)參數(shù)有值,添加條件查詢,附帶一個(gè)字符串的in查詢,下面這篇文章主要給大家介紹了關(guān)于Mybatis中使用in()查詢的方式,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • Java IO流 文件傳輸基礎(chǔ)

    Java IO流 文件傳輸基礎(chǔ)

    這篇文章主要介紹了Java IO流 文件傳輸基礎(chǔ)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • java中JsonObject與JsonArray轉(zhuǎn)換方法實(shí)例

    java中JsonObject與JsonArray轉(zhuǎn)換方法實(shí)例

    在項(xiàng)目日常開發(fā)中常常會(huì)遇到JSONArray和JSONObject的轉(zhuǎn)換,很多公司剛?cè)肼毜男∶刃聲?huì)卡在這里,下面這篇文章主要給大家介紹了關(guān)于java中JsonObject與JsonArray轉(zhuǎn)換方法的相關(guān)資料,需要的朋友可以參考下
    2023-04-04

最新評論