Mybatis高级多表查询学习 --懒加载 SQL

目录

数据准备

数据库准备

​编辑

实体类

src中的mapper层接口

1.对一的多表查询

mybatis中的mapper.xml

方法测试

对多查询的多表查询

mybatis中的mapper.xml

方法测试 

对一多表查询 懒加载

 mybatis中的xml

方法测试

对多的多表查询 懒加载

 mybatis中的xml

方法测试


今天学习的课程是mybatis中的多表查询,SQL中的多表查询主要有一对多,一对一,多对多, 本章主要讲解的是多表联查和加上懒加载的多表查询 所以讲解的就是对一和对多

数据准备

数据库准备

create table classes
(
    cid  int auto_increment comment '班级主键id'
        primary key,
    cname varchar(10) not null comment '班级名称'
);

create table student
(
    id   int auto_increment comment '主键id
'
        primary key,
    name varchar(10) not null comment '姓名',
    age  tinyint     not null comment '年龄',
    cid  int         not null comment '班级id'
);

实体类

package com.example.pojo;

import lombok.Data;

/**
 * @author:Dikk
 * @create: 2023-06-18 19:34
 * @Description: Student
 */
@Data
public class Student {
    /**
     * 学生id
     */
    private Integer id;
    /**
     * 学生姓名
     */
    private String name;
    /**
     * 学生年龄
     */
    private Integer age;
    /**
     * 学生所属班级
     */
    private Classes classes;
}
package com.example.pojo;

import lombok.Data;

import java.util.List;

/**
 * @author:Dikk
 * @create: 2023-06-18 19:35
 * @Description: Classes
 */
@Data
public class Classes {

    /**
     * 班级id
     */
    private Integer cid;
    /**
     * 班级名称
     */
    private String cname;
    /**
     * 班级对应的学生集合
     */
    private List<Student> studentList;

}

src中的mapper层接口

package com.example.mapper;

import com.example.pojo.Classes;
import org.apache.ibatis.annotations.Mapper;

/**
 * @author:Dikk
 * @create: 2023-06-18 19:24
 * @Description: ClassesMapper
 */
@Mapper
public interface ClassesMapper {

    /**
     * 根据班级id查询班级信息
     *
     * @param cid
     * @return
     */
    Classes selectByCid(Integer cid);

    /**
     * 根据班级id查询班级信息 懒加载使用
     *
     * @param cid
     * @return
     */
    Classes selectClassesByCid(Integer cid);

    /**
     * 根据cid查询班级 懒加载
     * @return
     */
    Classes selectByCidLazy(Integer cid);
}
package com.example.mapper;

import com.example.pojo.Student;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * @author:Dikk
 * @create: 2023-06-18 19:24
 * @Description: StudentMapper
 */
@Mapper
public interface StudentMapper {

    /**
     * 查询全部学生 懒加载
     *
     * @return
     */
    List<Student> selectAllLazy();

    /**
     * 根据班级id查询学生
     *
     * @param cid
     * @return
     */
    List<Student> selectByCid(Integer cid);

    /**
     * 查询全部学生
     *
     * @return
     */
    List<Student> selectAll();

}

1.对一的多表查询

mybatis中的mapper.xml

  <!--
            id="classesMap" 映射map的名称   type 返回值的数据类型
            这里的<id ====> 和 <result ====> 使用效果是一样的,只是语义不同,id为主键
            column 表示为表中的字段名  property 为实体类中对应的属性
            collection 在MyBatis中,collection是一个关键字,用于指定一个实体类与另一个实体类之间的关联关系。它通常用于一对多或多对多的关系中。
            property 关联的实体类对象 ofType 关联实体类的全类名
            此处的id和result和上面用法相同
    -->
    <resultMap id="classesMap" type="com.example.pojo.Classes">
        <id column="cid" property="cid"/>
        <result column="cname" property="cname"/>
        <collection property="studentList" ofType="com.example.pojo.Student">
            <id column="id" property="id"/>
            <result column="name" property="name"/>
            <result column="age" property="age"/>
        </collection>
    </resultMap>

    <select id="selectByCid" resultMap="classesMap">
        select *
        from classes c,
             student s
        where c.cid = #{cid}
          and c.cid = s.cid;
    </select>

xml中的studentmap标签的详细注解及作用讲解:

id="studentMap" 映射map的名称   type 返回值的数据类型
这里的<id ====> 和 <result ====> 使用效果是一样的,只是语义不同,id为主键
column 表示为表中的字段名  property 为实体类中对应的属性
association  在MyBatis中,association是一个关键字,用于指定一个实体类与另一个实体类之间的关联关系。
property 关联的实体类对象 javaType 关联实体类的全类名
此处的id和result和上面用法相同

其中的对应关系如下图

方法测试

 

 可以看到查到了所有学生的信息以及对应的班级信息

对多查询的多表查询

mybatis中的mapper.xml

    <!--
            id="classesMap" 映射map的名称   type 返回值的数据类型
            这里的<id ====> 和 <result ====> 使用效果是一样的,只是语义不同,id为主键
            column 表示为表中的字段名  property 为实体类中对应的属性
            collection 在MyBatis中,collection是一个关键字,用于指定一个实体类与另一个实体类之间的关联关系。它通常用于一对多或多对多的关系中。
            property 关联的实体类对象 ofType 关联实体类的全类名
            此处的id和result和上面用法相同
    -->
    <resultMap id="classesMap" type="com.example.pojo.Classes">
        <id column="cid" property="cid"/>
        <result column="cname" property="cname"/>
        <collection property="studentList" ofType="com.example.pojo.Student">
            <id column="id" property="id"/>
            <result column="name" property="name"/>
            <result column="age" property="age"/>
        </collection>
    </resultMap>

    <select id="selectByCid" resultMap="classesMap">
        select *
        from classes c,
             student s
        where c.cid = #{cid}
          and c.cid = s.cid;
    </select>

xml中的classesMap中的标签详解:

id="classesMap" 映射map的名称   type 返回值的数据类型
这里的<id ====> 和 <result ====> 使用效果是一样的,只是语义不同,id为主键
column 表示为表中的字段名  property 为实体类中对应的属性
collection 在MyBatis中,collection是一个关键字,用于指定一个实体类与另一个实体类之间的关联关系。它通常用于一对多或多对多的关系中。
property 关联的实体类对象 ofType 关联实体类的全类名
此处的id和result和上面用法相同

对应关系如下

方法测试 

 从测试结果中可以看出查出班级和班级对应的学生信息集合

懒加载 : 

这时我们发现,在查询过程中,在班级查询的时候无论我们是否需要学生信息的时候,SQL语句都会帮我们查询,这时候就需要引入懒加载,什么是懒加载

MyBatis中的懒加载(Lazy Loading)是一种延迟加载机制,用于优化数据访问性能。它的核心思想是在真正需要访问数据时才去执行SQL语句,以减少不必要的查询操作。

具体来说,当一个对象被查询出来后,如果该对象有关联的其他对象(比如一对多关系),默认情况下MyBatis会立即从数据库中查询这些关联对象并将其填充到该对象中。但如果使用了懒加载,则只有在真正访问这些关联对象时才会触发查询操作,否则它们就只是空值或者null。

使用懒加载可以减少不必要的数据库查询,提高系统的性能和响应速度。但需要注意的是,懒加载可能会带来一些额外的开销,比如增加了代码复杂度以及可能导致多次查询等问题,在实际使用时需要谨慎考虑。

以下,我们测试懒加载的具体使用效果

对一多表查询 懒加载

 mybatis中的xml

    <resultMap id="studentMapLazy" type="com.example.pojo.Student">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="age" property="age"/>

        <association property="classes"
                     javaType="com.example.pojo.Classes"
                     column="cid"
                     select="com.example.mapper.ClassesMapper.selectByCid"
                     fetchType="lazy"/>
    </resultMap>

    <select id="selectAllLazy" resultMap="studentMapLazy">
        select *
        from student;
    </select>

其中开启懒加载是用 fetchType标签, lazy则表示为懒加载

其中需要重点注意的是 association标签中的 colum标签中的cid表示的并不是classes类中的cid属性,而是student表中的cid字段

方法测试

 

尝试进行懒加载,只查询学生的信息,不查询班级的信息

 由上面的sql语句可以看到,我们只需要学生的信息,而不需要班级信息时,sql就只会执行查询学生部分的语句

对多的多表查询 懒加载

 mybatis中的xml

<resultMap id="classesMapLazy" type="com.example.pojo.Classes">
        <id column="cid" property="cid"/>
        <result column="cname" property="cname"/>
        <collection property="studentList"
                    ofType="com.example.pojo.Student"
                    column="cid"
                    select="com.example.mapper.StudentMapper.selectByCid"
                    fetchType="lazy">
            <id column="id" property="id"/>
            <result column="name" property="name"/>
            <result column="age" property="age"/>
        </collection>
    </resultMap>
    <select id="selectByCidLazy" resultMap="classesMapLazy">
        select *
        from classes
        where cid = #{cid};
    </select>

方法测试

 

 懒加载测试查询全部信息

 

 以上就是懒加载和多表联查的全部学习内容,共勉 

联想:

在学习的过程中,又发现了一些问题,既然在方法中都已经通过SQL查出了班级的所有信息,那是如何执行懒加载的,通过在查询语句和sout语句中间加入log打印日志并查看控制台的输出日志中发现,查询班级的SQL语句是必须执行的,懒加载的是否执行则是看下面的语句中是否有使用到,根据使用的情况再选择是否加载

 

 

如有错误,希望在评论区指正,阿里嘎多

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值