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

一文看懂Mybatis中的延遲加載

 更新時間:2023年10月27日 10:20:15   作者:來日淺談  
這篇文章主要介紹了一文看懂Mybatis中的延遲加載,延遲加載也稱為懶加載,是指在進(jìn)行表的關(guān)聯(lián)查詢時,按照設(shè)置延遲規(guī)則推遲對關(guān)聯(lián)對象的select查詢,MyBatis 的延遲加載只是對關(guān)聯(lián)對象的查詢有遲延設(shè)置,對于主加載對象都是直接執(zhí)行查詢語句的,需要的朋友可以參考下

1. 延遲加載簡介

MyBatis中的延遲加載,也稱為懶加載,是指在進(jìn)行表的關(guān)聯(lián)查詢時,按照設(shè)置延遲規(guī)則推遲對關(guān)聯(lián)對象的select查詢。例如在進(jìn)行一對多查詢的時候,只查詢出一方,當(dāng)程序中需要多方的數(shù)據(jù)時,mybatis再發(fā)出sql語句進(jìn)行查詢,這樣子延遲加載就可以的減少數(shù)據(jù)庫壓力。MyBatis 的延遲加載只是對關(guān)聯(lián)對象的查詢有遲延設(shè)置,對于主加載對象都是直接執(zhí)行查詢語句的。

好處:

先從單表查詢,需要時再從關(guān)聯(lián)表去關(guān)聯(lián)查詢,大大提高數(shù)據(jù)庫性能,因?yàn)椴樵儐伪硪汝P(guān)聯(lián)查詢多張表速度要快。

壞處:

因?yàn)橹挥挟?dāng)需要用到數(shù)據(jù)時,才會進(jìn)行數(shù)據(jù)庫查詢,這樣在大批量數(shù)據(jù)查詢時,因?yàn)椴樵児ぷ饕惨臅r間,所以可能造成用戶等待時間變長,造成用戶體驗(yàn)下降。

2. 關(guān)聯(lián)對象加載時機(jī)

MyBatis根據(jù)對關(guān)聯(lián)對象查詢的select語句的執(zhí)行時機(jī),分為三種類型:直接加載、侵入式延遲加載與深度延遲加載。

  • 直接加載:執(zhí)行完對主加載對象的 select 語句,馬上執(zhí)行對關(guān)聯(lián)對象的 select 查詢。
  • 侵入式延遲: 執(zhí)行對主加載對象的查詢時,不會執(zhí)行對關(guān)聯(lián)對象的查詢。但當(dāng)要訪問主加載對象的詳情屬性時,就會馬上執(zhí)行關(guān)聯(lián)對象的select查詢。
  • 深度延遲: 執(zhí)行對主加載對象的查詢時,不會執(zhí)行對關(guān)聯(lián)對象的查詢。訪問主加載對象的詳情時也不會執(zhí)行關(guān)聯(lián)對象的select查詢。只有當(dāng)真正訪問關(guān)聯(lián)對象的詳情時,才會執(zhí)行對關(guān)聯(lián)對象的 select 查詢。

需要注意的是, 延遲加載的應(yīng)用要求,關(guān)聯(lián)對象的查詢與主加載對象的查詢必須是分別進(jìn)行的 select 語句,不能是使用多表連接所進(jìn)行的select查詢。因?yàn)槎啾磉B接查詢,其實(shí)質(zhì)是對一張表的查詢,對由多個表連接后形成的一張表的查詢。會一次性將多張表的所有信息查詢出來。

MyBatis中對于延遲加載設(shè)置,只對于resultMap中的collection和association起作用,可以應(yīng)用到一對一、一對多、多對一、多對多的所有關(guān)聯(lián)關(guān)系查詢中。

下面以一對多關(guān)聯(lián)關(guān)系查詢?yōu)槔?,講解 MyBatis 中的延遲加載應(yīng)用。

3. 直接加載

主配置文件SqlMapConfig.xml中設(shè)置lazyLoadingEnabled為false,默認(rèn)為false。(因?yàn)槟J(rèn)式false,所以也可以不設(shè)置lazyLoadingEnabled)

<?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>
    <!-- 配置properties -->
    <properties resource="jdbcConfig.properties"></properties>
    
    <!-- 配置參數(shù) -->
    <settings>
        <!-- 關(guān)閉mybatis支持延遲加載 -->
        <setting name="lazyLoadingEnabled" value="false"/>
    </settings>
    
    <!-- 使用typeAliases配置別名,它只能配置domain中類的別名 -->
    <typeAliases>
        <package name="com.siyi.domain"></package>
    </typeAliases>
    <!-- 配置環(huán)境 -->
    <environments default="mysql">
        <!-- 配置mysql的環(huán)境 -->
        <environment id="mysql">
            <!-- 配置事務(wù) -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置連接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 映射配置文件 -->
    <mappers>
        <mapper resource="com/siyi/dao/IUserDao.xml"/>
        <mapper resource="com/siyi/dao/IAccountDao.xml"/>
    </mappers>
</configuration>

dao映射配置文件

<?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="com.siyi.dao.IUSerDao">

    <!-- 定義User的resultMap -->
    <resultMap id="userAccountMap" type="user">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="address" column="address"/>
        <result property="sex" column="sex"/>
        <result property="birthday" column="birthday"/>
        <collection property="accounts" ofType="account" select="com.siyi.dao.IAccountDao.findAccountByUid" column="id"/>
    </resultMap>

    <!-- 查詢所有 -->
    <select id="findAll" resultMap="userAccountMap">
        <!-- select * from user; -->
        select * from user
    </select>
</mapper>

測試

package com.siyi.test;

import com.siyi.dao.IUSerDao;
import com.siyi.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class UserTest {

    private InputStream in;
    private SqlSession session;
    private IUSerDao iuSerDao;

    @Before//用于在測試方法執(zhí)行之前執(zhí)行
    public void init() throws IOException {
        //1.讀取配置文件生成字節(jié)輸入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.獲取SqlSessionFactory對象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3.獲取SqlSession對象
        session = factory.openSession(true);
        //4.獲取DAO的代理對象
        iuSerDao = session.getMapper(IUSerDao.class);
    }

    @After//用于在測試方法之后執(zhí)行
    public void destroy() throws IOException {
        //事務(wù)提交
        //session.commit();
        //釋放資源
        session.close();
        in.close();
    }

    /**
     * 測試查詢所有
     * @throws IOException
     */
    @Test
    public void testFindAll() throws IOException {
        //5.執(zhí)行查詢所有方法
        List<User> users = iuSerDao.findAll();
    }
}

運(yùn)行過程中就查詢了所有的信息:

4. 侵入式延遲加載

主配置文件SqlMapConfig.xml中設(shè)置lazyLoadingEnabled為true,默認(rèn)為false,并且將aggressiveLazyLoading設(shè)置為true。(aggressiveLazyLoading默認(rèn)值為false (在 3.4.1 及之前的版本中默認(rèn)為 true))

<?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>
    <!-- 配置properties -->
    <properties resource="jdbcConfig.properties"></properties>
    
    <!-- 配置參數(shù) -->
    <settings>
        <!-- 開啟mybatis支持延遲加載 -->
        <setting name="lazyLoadingEnabled" value="false"/>
        <setting name="aggressiveLazyLoading" value="true"/>
    </settings>
    
    <!-- 使用typeAliases配置別名,它只能配置domain中類的別名 -->
    <typeAliases>
        <package name="com.siyi.domain"></package>
    </typeAliases>
    <!-- 配置環(huán)境 -->
    <environments default="mysql">
        <!-- 配置mysql的環(huán)境 -->
        <environment id="mysql">
            <!-- 配置事務(wù) -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置連接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 映射配置文件 -->
    <mappers>
        <mapper resource="com/siyi/dao/IUserDao.xml"/>
        <mapper resource="com/siyi/dao/IAccountDao.xml"/>
    </mappers>
</configuration>

dao映射配置文件不變

測試

package com.siyi.test;

import com.siyi.dao.IUSerDao;
import com.siyi.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class UserTest {

    private InputStream in;
    private SqlSession session;
    private IUSerDao iuSerDao;

    @Before//用于在測試方法執(zhí)行之前執(zhí)行
    public void init() throws IOException {
        //1.讀取配置文件生成字節(jié)輸入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.獲取SqlSessionFactory對象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3.獲取SqlSession對象
        session = factory.openSession(true);
        //4.獲取DAO的代理對象
        iuSerDao = session.getMapper(IUSerDao.class);
    }

    @After//用于在測試方法之后執(zhí)行
    public void destroy() throws IOException {
        //事務(wù)提交
        //session.commit();
        //釋放資源
        session.close();
        in.close();
    }

    /**
     * 測試查詢所有
     * @throws IOException
     */
    @Test
    public void testFindAll() throws IOException {
        //5.執(zhí)行查詢所有方法
        List<User> users = iuSerDao.findAll();
    }
}

沒有使用主對象的屬性(詳情)時,只執(zhí)行了主對象的查詢。

修改測試方法為

    @Test
    public void testFindAll() throws IOException {
        //5.執(zhí)行查詢所有方法
        List<User> users = iuSerDao.findAll();
		System.out.println(users.get(0).getUsername());
    }

在執(zhí)行主對象屬性(詳情)的時候,執(zhí)行關(guān)聯(lián)對象:

5. 深度延遲加載

主配置文件SqlMapConfig.xml中設(shè)置lazyLoadingEnabled為true,默認(rèn)為false,并且將aggressiveLazyLoading設(shè)置為false。(aggressiveLazyLoading默認(rèn)值為false (在 3.4.1 及之前的版本中默認(rèn)為 true))

<?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>
    <!-- 配置properties -->
    <properties resource="jdbcConfig.properties"></properties>
    
    <!-- 配置參數(shù) -->
    <settings>
        <!-- 開啟mybatis支持延遲加載 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
    
    <!-- 使用typeAliases配置別名,它只能配置domain中類的別名 -->
    <typeAliases>
        <package name="com.siyi.domain"></package>
    </typeAliases>
    <!-- 配置環(huán)境 -->
    <environments default="mysql">
        <!-- 配置mysql的環(huán)境 -->
        <environment id="mysql">
            <!-- 配置事務(wù) -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置連接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 映射配置文件 -->
    <mappers>
        <mapper resource="com/siyi/dao/IUserDao.xml"/>
        <mapper resource="com/siyi/dao/IAccountDao.xml"/>
    </mappers>
</configuration>

dao映射配置文件不變

測試

package com.siyi.test;

import com.siyi.dao.IUSerDao;
import com.siyi.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class UserTest {

    private InputStream in;
    private SqlSession session;
    private IUSerDao iuSerDao;

    @Before//用于在測試方法執(zhí)行之前執(zhí)行
    public void init() throws IOException {
        //1.讀取配置文件生成字節(jié)輸入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.獲取SqlSessionFactory對象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3.獲取SqlSession對象
        session = factory.openSession(true);
        //4.獲取DAO的代理對象
        iuSerDao = session.getMapper(IUSerDao.class);
    }

    @After//用于在測試方法之后執(zhí)行
    public void destroy() throws IOException {
        //事務(wù)提交
        //session.commit();
        //釋放資源
        session.close();
        in.close();
    }

    /**
     * 測試查詢所有
     * @throws IOException
     */
    @Test
    public void testFindAll() throws IOException {
        //5.執(zhí)行查詢所有方法
        List<User> users = iuSerDao.findAll();
        System.out.println(users.get(0).getUsername());
    }
}

沒有用到關(guān)聯(lián)對象時,只查詢主對象一次

修改測試方法

    @Test
    public void testFindAll() throws IOException {
        //5.執(zhí)行查詢所有方法
        List<User> users = iuSerDao.findAll();
        System.out.println(users.get(0).getAccounts());
    }

用到關(guān)聯(lián)對象數(shù)據(jù)的時候執(zhí)行關(guān)聯(lián)對象的查詢。

6. 延遲加載總結(jié)

延遲加載一般就是按需加載,在需要查詢的時候再去查詢,使用延遲加載可以避免表連接查詢,表連接查詢比單表查詢的效率低,但是它需要多次與數(shù)據(jù)庫進(jìn)行交互,所以延遲加載使用需謹(jǐn)慎。

關(guān)于延遲加載有兩個重要的設(shè)置:lazyLoadingEnabled表示延遲加載是否開啟,如果設(shè)置為true表示開啟,此時還需要設(shè)置aggressiveLazyLoading為false,才能做到按需加載,如果aggressiveLazyLoading設(shè)置為true則按需加載關(guān)閉,此時只要加載了某個屬性就會將所有屬性都加載。

lazyLoadingEnabled的默認(rèn)值為false

aggressiveLazyLoading的默認(rèn)值為true

注意: 延遲加載的應(yīng)用要求,關(guān)聯(lián)對象的查詢與主加載對象的查詢必須是分別進(jìn)行的 select 語句,不能是使用多表連接所進(jìn)行的select查詢。

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

相關(guān)文章

  • Springboot創(chuàng)建子父工程過程圖解

    Springboot創(chuàng)建子父工程過程圖解

    這篇文章主要介紹了Springboot創(chuàng)建子父工程過程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • 策略模式:告別if else

    策略模式:告別if else

    你是不是還在寫著大量的if else語句,if else 不僅難以維護(hù)不易擴(kuò)展,而且使代碼臃腫不堪,想不想讓你的業(yè)務(wù)代碼更加的健壯,更易擴(kuò)展,那你一定要學(xué)一學(xué)今天的主角策略模式
    2021-06-06
  • java實(shí)現(xiàn)五子棋大戰(zhàn)

    java實(shí)現(xiàn)五子棋大戰(zhàn)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)五子棋大戰(zhàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • java后臺本地文件轉(zhuǎn)為MultipartFile類型的實(shí)現(xiàn)方式

    java后臺本地文件轉(zhuǎn)為MultipartFile類型的實(shí)現(xiàn)方式

    在Java后臺將本地文件轉(zhuǎn)換為MultipartFile類型,可以通過使用FileItemFactory創(chuàng)建FileItem,然后使用CommonsMultipartFile類構(gòu)造一個MultipartFile對象,將本地文件流轉(zhuǎn)換為MultipartFile,getMultipartFiles()和getMultipartFiles()方法
    2025-02-02
  • WebDriver中實(shí)現(xiàn)對特定的Web區(qū)域截圖方法

    WebDriver中實(shí)現(xiàn)對特定的Web區(qū)域截圖方法

    這篇文章主要介紹了WebDriver中實(shí)現(xiàn)對特定的Web區(qū)域截圖方法,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2015-06-06
  • mybatis collection關(guān)聯(lián)查詢多個參數(shù)方式

    mybatis collection關(guān)聯(lián)查詢多個參數(shù)方式

    在使用MyBatis進(jìn)行關(guān)聯(lián)查詢時,往往需要根據(jù)多個參數(shù)進(jìn)行查詢,例如,使用evtId和businessType作為查詢條件,同時在resultMap中配置id和businessType1作為結(jié)果映射,這種情況下,可以通過<sql>標(biāo)簽定義參數(shù)模板,或者使用@Param注解指定參數(shù)名稱
    2024-10-10
  • Java從入門到起飛之變量與運(yùn)算符詳解

    Java從入門到起飛之變量與運(yùn)算符詳解

    這篇文章主要介紹了Java編程語言中的關(guān)鍵字、標(biāo)識符、變量、基本數(shù)據(jù)類型以及運(yùn)算符等基本概念和用法,它涵蓋了變量聲明、賦值、類型轉(zhuǎn)換、字符串操作以及運(yùn)算符優(yōu)先級等內(nèi)容,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-03-03
  • IDEA中java斷言assert語法及使用

    IDEA中java斷言assert語法及使用

    這篇文章主要介紹了IDEA中java斷言assert語法詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Open-Feign整合hystrix降級熔斷實(shí)戰(zhàn)記錄

    Open-Feign整合hystrix降級熔斷實(shí)戰(zhàn)記錄

    這篇文章主要介紹了Open-Feign整合hystrix降級熔斷實(shí)戰(zhàn)記錄,本文通過實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • 詳解SpringMVC @RequestBody接收J(rèn)son對象字符串

    詳解SpringMVC @RequestBody接收J(rèn)son對象字符串

    這篇文章主要介紹了詳解SpringMVC @RequestBody接收J(rèn)son對象字符串,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01

最新評論