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

Myth丶恋晨 2024-04-01 12:09 123阅读 0赞

MyBatis一对多映射查询

  • 一、两种方式
  • 二、使用collection标签
  • 三、分步查询
  • 四、延迟加载

往期文章:
一文彻底搞懂Mybatis系列(一)之mybatis入门
一文彻底搞懂Mybatis系列(二)之mybatis事务管理机制深度剖析
一文彻底搞懂Mybatis系列(三)之mybatis完成增删改查CURD功能超级详细
一文彻底搞懂Mybatis系列(四)之mybatis核心配置文件详解
一文彻底搞懂Mybatis系列(五)之手写Mybatis框架简单探索版
一文彻底搞懂Mybatis系列(六)之在WEB应用中使用Mybatis
一文彻底搞懂Mybatis系列(七)之使用Mybatis的小技巧
一文彻底搞懂Mybatis系列(八)之Mybatis参数处理
一文彻底搞懂Mybatis系列(九)之Mybatis动态SQL标签总结
一文彻底搞懂Mybatis系列(十)之SqlSession、SqlSessionFactory和SqlSessionFactoryBuilder详解
一文彻底搞懂Mybatis系列(十一)之MyBatis多对一映射查询
一文彻底搞懂Mybatis系列(十二)之MyBatis多对一映射延迟加载(association和lazyLoadingEnabled)
一文彻底搞懂Mybatis系列(十三)之MyBatis一对多映射查询
一文彻底搞懂Mybatis系列(十四)之MyBatis一级缓存
一文彻底搞懂Mybatis系列(十五)之MyBatis二级缓存
一文彻底搞懂Mybatis系列(十六)之MyBatis集成EhCache
一文彻底搞懂Mybatis系列(十七)之MyBatis使用分页插件PageHelper

一、两种方式

1、使用collection标签
2、分步查询

两张表如下:
学生表 t_stu 和 班级表 t_clazz,学生表的cid和班级表的cid关联,
表示一个班级有多个学生
在这里插入图片描述

二、使用collection标签

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

  1. public class Clazz {
  2. private Integer cid;
  3. private String name;
  4. private List<Stu> stus;
  5. .....此处省略getset、构造器方法

ClazzMapper接口

  1. public interface ClazzMapper {
  2. public Clazz selectSingAsManyByCollection(Integer cid);
  3. }

ClazzMapper.xml文件

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

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.powernode.mybatis.mapper.ClazzMapper">
  6. <!--方式一:colleciton-->
  7. <resultMap id="singAsManyByCollectionMap" type="Clazz">
  8. <id property="cid" column="cid"/>
  9. <result property="name" column="name"/>
  10. <collection property="stus" ofType="Stu">
  11. <id property="sid" column="sid"/>
  12. <result property="name" column="name"/>
  13. </collection>
  14. </resultMap>
  15. <select id="selectSingAsManyByCollection" resultMap="singAsManyByCollectionMap">
  16. select c.cid,c.name,s.sid,s.name,s.cid
  17. from t_clazz c LEFT JOIN t_stu s on c.cid = s.cid
  18. where c.cid = #{cid}
  19. </select>
  20. </mapper>

测试类趴一下

  1. @Test
  2. public void testSingAsManyByCollection(){
  3. SqlSession sqlSession = SqlSessionUtil.openSqlSession();
  4. ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);
  5. Clazz clazz = mapper.selectSingAsManyByCollection(1000);
  6. System.out.println(clazz.toString());
  7. sqlSession.close();
  8. }

运行结果:

  1. 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 = ?
  2. 20:45:36.484 default [main] DEBUG c.p.m.m.C.selectSingAsManyByCollection - ==> Parameters: 1000(Integer)
  3. 20:45:36.566 default [main] DEBUG c.p.m.m.C.selectSingAsManyByCollection - <== Total: 3
  4. Clazz{
  5. cid=1000, name='高三一班', stus=[Stu{
  6. sid=1, name='高三一班', clazz=null}, Stu{
  7. sid=2, name='高三一班', clazz=null}, Stu{
  8. sid=3, name='高三一班', clazz=null}]}

三、分步查询

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

  1. public class Clazz {
  2. private Integer cid;
  3. private String name;
  4. private List<Stu> stus;
  5. .....此处省略getset、构造器方法

pojo类 Stu

  1. public class Stu {
  2. private Integer sid;
  3. private String name;
  4. .....此处省略getset、构造器方法

ClazzMapper接口

  1. public interface ClazzMapper {
  2. public Clazz selectSingAsManyByCidStep1(Integer cid);
  3. }

StuMapper接口

  1. public interface StuMapper {
  2. public List<Stu> selectByCid(Integer cid);
  3. }

StuMapper.xml文件

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.powernode.mybatis.mapper.StuMapper">
  6. <select id="selectByCid" resultType="Stu">
  7. select sid,name,cid from t_stu where cid=#{cid}
  8. </select>
  9. </mapper>

ClazzMapper.xml文件

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.powernode.mybatis.mapper.ClazzMapper">
  6. <!--方式二:分步查询-->
  7. <resultMap id="singAsManyStepMap" type="Clazz">
  8. <id property="cid" column="cid"/>
  9. <result property="name" column="name"/>
  10. <collection property="stus"
  11. select="com.powernode.mybatis.mapper.StuMapper.selectByCid"
  12. column="cid"/>
  13. </resultMap>
  14. <select id="selectSingAsManyByCidStep1" resultMap="singAsManyStepMap">
  15. select c.cid,c.name from t_clazz c
  16. where c.cid = #{cid}
  17. </select>
  18. </mapper>

测试类趴一下

  1. @Test
  2. public void testSingAsManyByCidStep(){
  3. SqlSession sqlSession = SqlSessionUtil.openSqlSession();
  4. ClazzMapper mapper = sqlSession.getMapper(ClazzMapper.class);
  5. Clazz clazz = mapper.selectSingAsManyByCidStep1(1001);
  6. System.out.println(clazz);
  7. sqlSession.close();
  8. }

运行结果如下:

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

发表评论

表情:
评论列表 (有 0 条评论,123人围观)

还没有评论,来说两句吧...

相关阅读