延迟加载也叫惰性加载或者懒加载,使⽤延迟是为了提⾼程序的运⾏效率,具体是通过尽量少执⾏ SQL 语句来提升效率。Java 程序与数据库的交互频率越低越好,MyBatis 提供的延迟加载功能就可以做到这 ⼀点。

  延迟加载是作⽤于级联查询的场景下:

    查询⽬标表时,如果仅查询⽬标表就可以获取相应的字段,则不需要查询级联表;

    除⾮必须查询级联表才能获取的字段,则查询级联表,通过延迟加载可以有效减少 SQL 语句的执⾏次数。

  延迟加载的思路:

    将级联查询的 SQL 语句进⾏拆分,不要⽤⼀条 SQL 语句进⾏级联查询,改为两条 SQL 的单表查询。

    当我们查询 Order 的时候,如果没有访问 customer 的属性,则只发送⼀条 SQL 语句查询 Order;

    如果需要访问 customer 的属性,则发送两条 SQL 语句查询 Order 和 Customer。

示例:

1、创建数据库

2、创建实体类

package com.sunjian.entity;

import java.util.List;

/**
 * @author sunjian
 * @date 2020/3/23 14:37
 */
public class Customer {
    private Long id;
    private String name;
    private List<Order> orders;

    public List<Order> getOrders() {
        return orders;
    }

    public void setOrders(List<Order> orders) {
        this.orders = orders;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", orders=" + orders +
                '}';
    }
}
package com.sunjian.entity;

/**
 * @author sunjian
 * @date 2020/3/23 14:38
 */
public class Order {
    public Long getId() {
        return id;
    }

    @Override
    public String toString() {
        return "Order{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", customer=" + customer +
                '}';
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    private Long id;
    private String name;
    private Customer customer;

}

3、创建repository接口

package com.sunjian.repository;

import com.sunjian.entity.Customer;
import com.sunjian.entity.Order;

/**
 * @author sunjian
 * @date 2020/3/23 14:41
 */
public interface CustomerRepository {
    public Customer findCustomerById(Long id);
}
package com.sunjian.repository;

import com.sunjian.entity.Order;

/**
 * @author sunjian
 * @date 2020/3/23 14:41
 */
public interface OrderRepository {
    public Order findOrderById(Long id);
}

4、创建repository.xml编写SQL(单独查询)

<?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.sunjian.repository.CustomerRepository">

    <select id="findCustomerById" parameterType="java.lang.Long" resultType="com.sunjian.entity.Customer">
            select * from t_customer where id = #{id}
    </select>
</mapper>
<?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.sunjian.repository.OrderRepository">

    <resultMap id="orderMap" type="com.sunjian.entity.Order">
        <id property="id" column="id"></id>
        <result property="name" column="name"></result>
        <!-- 将查询结果中的cid字段,映射为另一个接口中的参数;达到级联查询-->
        <association property="customer" javaType="com.sunjian.entity.Customer" column="cid" select="com.sunjian.repository.CustomerRepository.findCustomerById"></association>
    </resultMap>

    <select id="findOrderById" parameterType="java.lang.Long" resultMap="orderMap">
            select * from t_order where id = #{id}
    </select>
</mapper>

5、创建config.xml全局配置文件(开启延迟加载配置),将repository.xml注册到config.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>
    <!-- 打印SQL语句 -->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!-- 开启延迟加载 -->
        <setting name="lazyLoadingEnabled" value="true"/>
    </settings>

    <!-- 配置 MyBatis 数据源 -->
    <environments default="development">
        <environment id="development">
            <!-- JDBC事务管理 -->
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 注册 -->
    <mappers>
        <!-- 单表 -->
        <mapper resource="com/sunjian/mapper/UserMapper.xml"></mapper>
        <mapper resource="com/sunjian/repository/UserRepository.xml"></mapper>

        <!-- 多表 一对一 -->
        <mapper resource="com/sunjian/repository/StudentRepository.xml"></mapper>
        <!-- 多表 一对多 -->
        <mapper resource="com/sunjian/repository/ClassesRepository.xml"></mapper>
        <!-- 多表 多对多 -->
        <mapper resource="com/sunjian/repository/CourseRepository.xml"></mapper>

        <mapper resource="com/sunjian/repository/OrderRepository.xml"></mapper>
        <mapper resource="com/sunjian/repository/CustomerRepository.xml"></mapper>

    </mappers>

</configuration>

6、创建测试类

package com.sunjian.test;

import com.sunjian.entity.Customer;
import com.sunjian.entity.Order;
import com.sunjian.entity.User;
import com.sunjian.repository.CustomerRepository;
import com.sunjian.repository.OrderRepository;
import com.sunjian.repository.UserRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

/**
 * @author sunjian
 * @date 2020/3/22 10:20
 */
public class Test {
    public static void main(String[] args) {

        // Mapper 代理实现自定义接口
        InputStream inputStream = Order.class.getClassLoader().getResourceAsStream("config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 获取接口的处理对象
        OrderRepository orderRepository = sqlSession.getMapper(OrderRepository.class);
        Order order = orderRepository.findOrderById(1L);
        System.out.println(order.getName());

    }

}

开启延迟加载

Opening JDBC Connection
Created connection 793315160.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2f490758]
==>  Preparing: select * from t_order where id = ?
==> Parameters: 1(Long)
<==    Columns: id, name, cid
<==        Row: 1, 订单1, 1
<==      Total: 1
订单1

未开启延迟加载

Opening JDBC Connection
Created connection 793315160.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2f490758]
==>  Preparing: select * from t_order where id = ?
==> Parameters: 1(Long)
<==    Columns: id, name, cid
<==        Row: 1, 订单1, 1
====>  Preparing: select * from t_customer where id = ?
====> Parameters: 1(Long)
<====    Columns: id, name
<====        Row: 1, 张三
<====      Total: 1
<==      Total: 1
订单1

OK.

MyBatis框架——延迟加载的更多相关文章

  1. 在mybatis框架中,延迟加载与连表查询的差异

    1.引子 mybatis的延迟加载,主要应用于一个实体类中有复杂数据类型的属性,包括一对一和一对多的关系(在xml中用collection.association标签标识).这个种属性往往还对应着另一 ...

  2. Hibernate框架与Mybatis框架的对比

    学习了Hibernate和Mybatis,但是一直不太清楚他们两者的区别的联系,今天在网上翻了翻,就做了一下总结,希望对大家有帮助! 原文:http://blog.csdn.net/firejuly/ ...

  3. MyBatis 框架笔记

    Mybatis 框架笔记   ------技术源于热爱! 获取更多内容请关注小编的个人微信公众平台 1       Mybatis入门 1.1     单独使用jdbc编程问题总结 1.1.1  jd ...

  4. 【mybatis】使用mybatis框架中踩过的坑

    好久没来记录一下自己的学习情况,最近都在学框架,今天来记录一下关于mybatis框架的学习过程中碰过的一些问题: 以下内容可能稍微有点凌乱,因为是把之前遇到过的错误或异常都集中一起了,不过我已经把问题 ...

  5. mybatis的延迟加载、一级缓存、二级缓存

    mybatis的延迟加载.一级缓存.二级缓存 mybatis是什么? mybatis是一个持久层框架,是apache下的开源项目,前身是itbatis,是一个不完全的ORM框架,mybatis提供输入 ...

  6. Spring MVC 学习总结(十)——Spring+Spring MVC+MyBatis框架集成(IntelliJ IDEA SSM集成)

    与SSH(Struts/Spring/Hibernate/)一样,Spring+SpringMVC+MyBatis也有一个简称SSM,Spring实现业务对象管理,Spring MVC负责请求的转发和 ...

  7. MyBatis框架的使用及源码分析(九) Executor

    从<MyBatis框架的使用及源码分析(八) MapperMethod>文中我们知道执行Mapper的每一个接口方法,最后调用的是MapperMethod.execute方法.而当执行Ma ...

  8. MyBatis框架的使用及源码分析(三) 配置篇 Configuration

    从上文<MyBatis框架中Mapper映射配置的使用及原理解析(二) 配置篇 SqlSessionFactoryBuilder,XMLConfigBuilder> 我们知道XMLConf ...

  9. MyBatis 框架 基础应用

    1.ORM的概念和优势 概念: 对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据 ...

随机推荐

  1. TCP\IP协议簇-分层模型

    OSI 模型   数据单元 层 功能 主机层 Data(数据) 7. 应用层 网络进程到应用程序. 6. 表示层 数据表示形式,加密和解密,把机器相关的数据转换成独立于机器的数据. 5. 会话层 主机 ...

  2. 在 mac osx 上安装OpenOffice并以服务的方式启动

    OpenOffice是Apache基金会旗下的一款先进的开源办公软件套件,包含文本文档.电子表格.演示文稿.绘图.数据库等.包含Microsoft office所有功能.它不仅可以作为桌面应用供普通用 ...

  3. 为啥java要使用 set ()和get()方法---封装

    封装性:属性封装,方法封装,类封装,组件封装等 例如:如果属性没有封装,那么在本类对象之外创建对象后,可以直接访问属性 private关键字,只能在本类中访问,想要在外部访问私有属性,我们需要提供公有 ...

  4. 01Java代码是怎么运行的

    从虚拟机视角来看,执行 Java 代码首先需要将它编译而成的 class 文件加载到 Java 虚拟机中.加载后的 Java 类会被存放于方法区(Method Area)中.实际运行时,虚拟机会执行方 ...

  5. js操作复选框

    js操作复选框 JavaScript 代码: //复选框全选 $(function () { $("#select_all").click(function () { $(&quo ...

  6. LeetCode 题解 | 面试题 10.01. 合并排序的数组

    给定两个排序后的数组 A 和 B,其中 A 的末端有足够的缓冲空间容纳 B. 编写一个方法,将 B 合并入 A 并排序. 初始化 A 和 B 的元素数量分别为 m 和 n. 示例: 输入: A = [ ...

  7. C# InputStream获取后乱码处理

    Post推送过来的数据流获取后部分中文出现乱码,晚上找了好多办法,不如朋友鼎力相助,哈哈哈~不说废话了上代码把 旧代码基本是网上普遍写法,字段不长用起来不会有乱码情况,但是传送字段一旦过长,超过byt ...

  8. XML学习笔记--背诵版

    前言 一直想系统性的学XML,就没时间学,今晚抽出几个小时时间学完了XML.过几天再过来看看,背一背应该就差不多,记得东西较多,没什么难理解的. XML数据传输格式 第一章 XML概述 1.1 引入 ...

  9. hadoop之完全分布式集群配置(centos7)

    一.基础环境 现在我们有两台虚拟机了,再克隆两台: 克隆好之后需要做三件事:1.更改主机名称 2.修改ip地址 3.将ip地址和对应的主机号加入到/etc/hosts文件中 1.永久修改主机名 hos ...

  10. 安装msyql报错——error: Failed dependencies

    报错原因: 1.存在两个版本的msyql-community-release. 解决方法: 1.将不要的哪个进行去除,使用命令: rpm -e --nodeps mysql80-community-r ...