一文彻底搞懂Mybatis系列(十三)之MyBatis一对多映射查询

简介: 一文彻底搞懂Mybatis系列(十三)之MyBatis一对多映射查询

一、两种方式

1、使用collection标签

2、分步查询

两张表如下:

学生表 t_stu 和 班级表 t_clazz,学生表的cid和班级表的cid关联,

表示一个班级有多个学生

二、使用collection标签

pojo类 Clazz

注意:里面的学生集合类,因为一个班级有多个学生,所以使用集合来存放学生类

public class Clazz {
    private Integer cid;
    private String name;
    private List<Stu> stus;
    .....此处省略get、set、构造器方法

ClazzMapper接口

public interface ClazzMapper {
    public Clazz selectSingAsManyByCollection(Integer cid);
}

ClazzMapper.xml文件

注意:collection 标签的ofType属性,表示集合的类型,比如List,集合的类型就是Stu类

<?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.powernode.mybatis.mapper.ClazzMapper">
    <!--方式一:colleciton-->
    <resultMap id="singAsManyByCollectionMap" type="Clazz">
        <id property="cid" column="cid"/>
        <result property="name" column="name"/>
        <collection property="stus" ofType="Stu">
            <id property="sid" column="sid"/>
            <result property="name" column="name"/>
        </collection>
    </resultMap>
    <select id="selectSingAsManyByCollection" resultMap="singAsManyByCollectionMap">
        select c.cid,c.name,s.sid,s.name,s.cid 
        from t_clazz c LEFT JOIN t_stu s on c.cid = s.cid
        where c.cid = #{cid}
    </select>
</mapper>

测试类趴一下

@Test
    public void testSingAsManyByCollection(){
        SqlSession sqlSession = SqlSessionUtil.openSqlSession();
        ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);
        Clazz clazz = mapper.selectSingAsManyByCollection(1000);
        System.out.println(clazz.toString());
        sqlSession.close();
    }

运行结果:

20:45:36.399 default [main] DEBUG c.p.m.m.C.selectSingAsManyByCollection - ==>  Preparing: select c.cid,c.name,s.sid,s.name,s.cid from t_clazz c LEFT JOIN t_stu s on c.cid = s.cid where c.cid = ?
20:45:36.484 default [main] DEBUG c.p.m.m.C.selectSingAsManyByCollection - ==> Parameters: 1000(Integer)
20:45:36.566 default [main] DEBUG c.p.m.m.C.selectSingAsManyByCollection - <==      Total: 3
Clazz{cid=1000, name='高三一班', stus=[Stu{sid=1, name='高三一班', clazz=null}, Stu{sid=2, name='高三一班', clazz=null}, Stu{sid=3, name='高三一班', clazz=null}]}

三、分步查询

pojo类 Clazz

注意:里面的学生集合类,因为一个班级有多个学生,所以使用集合来存放学生类

public class Clazz {
    private Integer cid;
    private String name;
    private List<Stu> stus;
    .....此处省略get、set、构造器方法

pojo类 Stu

public class Stu {
    private Integer sid;
    private String name;
    .....此处省略get、set、构造器方法

ClazzMapper接口

public interface ClazzMapper {
    public Clazz selectSingAsManyByCidStep1(Integer cid);
}

StuMapper接口

public interface StuMapper {
    public List<Stu> selectByCid(Integer cid);
}

StuMapper.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="com.powernode.mybatis.mapper.StuMapper">
    <select id="selectByCid" resultType="Stu">
        select sid,name,cid from t_stu where cid=#{cid}
    </select>
</mapper>

ClazzMapper.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="com.powernode.mybatis.mapper.ClazzMapper">
    <!--方式二:分步查询-->
    <resultMap id="singAsManyStepMap" type="Clazz">
        <id property="cid" column="cid"/>
        <result property="name" column="name"/>
        <collection property="stus"
                    select="com.powernode.mybatis.mapper.StuMapper.selectByCid"
                    column="cid"/>
    </resultMap>
    <select id="selectSingAsManyByCidStep1" resultMap="singAsManyStepMap">
        select c.cid,c.name from t_clazz c
        where c.cid = #{cid}
    </select>
</mapper>

测试类趴一下

@Test
    public void testSingAsManyByCidStep(){
        SqlSession sqlSession = SqlSessionUtil.openSqlSession();
        ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);
        Clazz clazz = mapper.selectSingAsManyByCidStep1(1001);
        System.out.println(clazz);
        sqlSession.close();
    }

运行结果如下:

20:56:05.559 default [main] DEBUG c.p.m.m.C.selectSingAsManyByCidStep1 - ==>  Preparing: select c.cid,c.name from t_clazz c where c.cid = ?
20:56:05.700 default [main] DEBUG c.p.m.m.C.selectSingAsManyByCidStep1 - ==> Parameters: 1001(Integer)
20:56:05.949 default [main] DEBUG c.p.m.m.C.selectSingAsManyByCidStep1 - <==      Total: 1
20:56:05.953 default [main] DEBUG c.p.m.mapper.StuMapper.selectByCid - ==>  Preparing: select sid,name,cid from t_stu where cid=?
20:56:05.953 default [main] DEBUG c.p.m.mapper.StuMapper.selectByCid - ==> Parameters: 1001(Integer)
20:56:05.957 default [main] DEBUG c.p.m.mapper.StuMapper.selectByCid - <==      Total: 2
Clazz{cid=1001, name='高三二班', stus=[Stu{sid=4, name='赵六', clazz=null}, Stu{sid=5, name='钱七', clazz=null}]}

四、延迟加载

在进行一对多查询时,如果使用分步查询的方式,此时可以对查询进行延迟加载控制。

通俗点讲就是:用的时候再执行查询语句。不用的时候不查询。

作用:提高性能。尽可能的不查,或者说尽可能的少查。来提高效率。

2、开启延迟加载的两种方式

(1)局部延迟加载

在mybatis的association标签中添加 fetchType=“lazy”

注意:

默认情况下是没有开启延迟加载的。需要设置:fetchType=“lazy”

这种在association标签中配置fetchType=“lazy”,是局部的设置,只对当前的association关联的sal语句起作用。

(2)全局延迟加载

在实际的开发中,大部分都是需要使用延迟加载的,所以建议开启全部的延迟加载机制:

在mybatis核心配置文件中添加全局配置:lazyLoadingEnabled=true

实际开发中的模式:

把全局的延迟加载打开。

如果某一步不需要使用延迟加载,请设置:fetchType=“eager”

具体的延迟加载描述,可以看我之前专门介绍文章

https://blog.csdn.net/weixin_43860634/article/details/127585161


相关文章
|
2月前
|
Java 数据库连接 数据库
mybatis查询数据,返回的对象少了一个字段
mybatis查询数据,返回的对象少了一个字段
192 8
|
20天前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
25天前
|
SQL 安全 Java
MyBatis-Plus条件构造器:构建安全、高效的数据库查询
MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。
14 1
MyBatis-Plus条件构造器:构建安全、高效的数据库查询
|
1月前
|
SQL Java 数据库连接
mybatis如何仅仅查询某个表的几个字段
【10月更文挑战第19天】mybatis如何仅仅查询某个表的几个字段
40 1
|
2月前
|
SQL XML Java
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
文章介绍了MyBatis中高级查询的一对多和多对一映射处理,包括创建数据库表、抽象对应的实体类、使用resultMap中的association和collection标签进行映射处理,以及如何实现级联查询和分步查询。此外,还补充了延迟加载的设置和用法。
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
|
1月前
|
SQL XML Java
Mybatis中一对一和一对多的处理
这篇文章讲解了在Mybatis中如何处理一对一和一对多的关系映射,包括使用association和collection标签的具体方法。
26 1
|
3月前
|
Java 数据库连接 mybatis
后端框架的学习----mybatis框架(9、多对一处理和一对多处理)
这篇文章介绍了在MyBatis框架中如何处理多对一和一对多的关联查询,通过定义`<resultMap>`和使用`<association>`与`<collection>`元素来实现对象间的关联映射。
|
4月前
|
SQL Java 数据库连接
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
94 3
|
4月前
|
Java 数据库连接 mybatis
Mybatis查询传递单个参数和传递多个参数用法
Mybatis查询传递单个参数和传递多个参数用法
68 11
若依修改,集成mybatisplus报错,若依集成mybatisplus,总是找不到映射是怎么回事只要是用mp的方法就找报,改成mybatisPlus配置一定要改
若依修改,集成mybatisplus报错,若依集成mybatisplus,总是找不到映射是怎么回事只要是用mp的方法就找报,改成mybatisPlus配置一定要改