Mybatis懒加载

懒加载是什么?

按需加载所需内容,当调用到关联的数据时才与数据库交互否则不交互,能大大提高数据库性能,并不是所有场景下使用懒加载都能提高效率。

Mybatis懒加载:resultMap里面的association、collection有延迟加载功能

懒加载针对什么使用?为什么要用懒加载?

懒加载针对级联使用的,懒加载的目的是减少内存的浪费和减轻系统负担


举例:

查询所有用户信息(其下有多个收货地址)

sql 复制代码
select b.id ,b.userName,b.userCode,a.*
from smbms_address a right join smbms_user b on a.userId = b.id

进行分步查询:当我需要查看地址的时候加载收货地址信息

sql 复制代码
-- 查询所有用户信息
select * from smbms_user
-- 查询地址信息
select * from smbms_address where userId = #{id}

以上为单表查询,效率相对于大数据量的关联查询要高

Mybatis懒加载实例

1、在Mybatis 主配置文件中开启懒加载

XML 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--引入properties文件-->
    <properties resource="database.properties"></properties>
    <!--配置打印sql语句-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>

        <!--在mybatis主配置文件中关闭自动映射-->
        <!--NONE  FULL全映射-->
        <setting name="autoMappingBehavior" value="FULL"/>
        <!-- 开启懒加载(延迟加载) -->
        <setting name="lazyLoadingEnabled" value="true"/>

    </settings>

    <!--起别名-->
    <typeAliases>
        <package name="com.hz.pojo"/>
    </typeAliases>
    
    <!--可以起多个environments-->
    <environments default="smbms">
        <environment id="smbms">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${user}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mappers/AddressMapper.xml"/>
        <mapper resource="mappers/UserMapper.xml"/>
    </mappers>

</configuration>

2、创建实体类等

java 复制代码
package com.hz.pojo;

import lombok.Data;

import java.io.Serializable;
import java.util.List;

@Data
public class User implements Serializable {
	private Long id; //id
	private String userCode; //用户编码
	private String userName; //用户名称
	private String userPassword; //用户密码
	private Integer gender;  //性别
	private String birthday;  //出生日期
	private String phone;   //电话
	private String address; //地址
	private Integer userRole;    //用户角色
	private Integer createdBy;   //创建者
	private String creationDate; //创建时间
	private Integer modifyBy;     //更新者
	private String modifyDate;   //更新时间

	private  Role role;	//用户角色对象

	private List<Address> addressList; //收货地址集合


}
java 复制代码
package com.hz.pojo;

import lombok.*;

@Setter
@Getter
@NoArgsConstructor //无参构造方法
@AllArgsConstructor //有参构造方法
@ToString
public class Address {
	private Long id;				//主键ID
	private String postCode; 		//邮编
	private String contact;			//联系人
	private String addressDesc;		//地址
	private String tel;				//联系电话
	private Integer createdBy; 		//创建者
	private String creationDate; 	//创建时间
	private Integer modifyBy; 		//更新者
	private String modifyDate;		//更新时间
	private User user;  			//所属用户对象

}

3、创建Dao接口和XML文件

XML 复制代码
   <!--懒加载-->

    <resultMap id="userMap1" type="User">
        <id property="id" column="id"/>
        <!-- 一对多  对象套集合 -->
        <collection property="addressList" column="id" ofType="Address" select="getAdd" fetchType="lazy">
            <id property="id" column="id"/>
        </collection>
    </resultMap>
    <select id="findUserList1" resultMap="userMap1">
        select * from smbms_user
    </select>
    <select id="getAdd" resultType="Address">
        select * from smbms_address where userId = #{id}
    </select>

因为 User表与 Address表 是一对多关联,所以使用resultMap的collection映射,在collection标签中,添加属性fetchType ,属性值为lazy ,表示懒加载。

4、测试

java 复制代码
    @Test
    public void findUserList1() {
        SqlSession sqlSession = MyBatisUtil.createSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        List<User> userList = userDao.findUserList1();
        for (User u :userList) {
            System.out.println("userName:"+u.getUserName());
        }
        //调用地址
//        List<User> userList = userDao.findUserList1();
//        for (User u :userList) {
//            List<Address> addressList = u.getAddressList();
//            System.out.println("userName:"+u.getUserName());
//            for (Address address :addressList) {
//                System.out.println("addressName:"+address.getContact());
//            }
//        }
    }

只查询 UserName :结果如下

组合查询时 :结果如下

相关推荐
IronMurphy6 小时前
SSM拷打第二讲!!!
java·spring·mybatis
C+-C资深大佬1 天前
SSM 框架(Spring + SpringMVC + MyBatis)
java·spring·mybatis
二王一个今1 天前
springboot security 权限控制---循环依赖问题
mybatis
落木萧萧8251 天前
为什么我把 MyBatisGX 设计成现在这样
mybatis·orm
代码旅人ing1 天前
Redis+Spring+MyBatis + 微服务 + 消息队列核心知识点(面试高频题目合集)
redis·spring·mybatis·java-rabbitmq
Devin~Y1 天前
大厂Java面试实录:Spring Boot/Cloud、Kafka、Redis、K8s 可观测性 + RAG/Agent(小Y翻车版)
java·spring boot·redis·spring cloud·kafka·kubernetes·mybatis
ppandss11 天前
JavaWeb从0到1-DAY11-MyBatis入门
java·tomcat·mybatis
JAVA面经实录9172 天前
MyBatis面试题库
java·mybatis
杨运交2 天前
[022][数据模块]基于雪花算法的 MyBatis-Plus 主键生成器设计与实现
mybatis
Mahir082 天前
MyBatis 深度解密:从执行流程到底层原理全解
java·后端·面试·mybatis