当前位置: 首页 > news >正文

MyBatis 之关联查询(一对一、一对多及多对多实现)

目录

1. MyBatis关联查询

2. 一对一关联查询

3. 一对多关联查询

4. 多对多关联查询

5. 总结


前言

在实际开发中,数据库表之间往往存在关联关系,多表关联查询是常见需求

MyBatis 作为优秀的持久层框架,提供了灵活的关联查询处理方式

本文将聚焦 MyBatis 中一对一、一对多及多对多关联查询的核心实现,帮助开发者快速掌握通过映射配置处理表间关联的方法

个人主页:艺杯羹

1. MyBatis关联查询

MyBatis的关联查询分为一对一关联查询 一对多关联查询

  • 查询对象时,将关联的另一个对象查询出来,就是一对一关联查询。
  • 查询对象时,将关联的另一个对象的集合查询出来,就是一对多关联查询。

例如有学生类和班级类:
一个学生对应一个班级,也就是学生类中有一个班级属性,这就是一对一关系

一个班级对应多个学生,也就是班级类中有一个学生集合属性,这就是一对多关系

实体类设计如下:

public class Student {private int sid;private String name;private int age;private String sex;private Classes classes;// 省略getter/setter/toString
}public class Classes {private int cid;private String className;private List<Student> studentList;// 省略getter/setter/toString
}

2. 一对一关联查询

查询学生时,将关联的一个班级对象查询出来,就是一对一关联查询
关联对象类标签:association

创建持久层接口

public interface StudentMapper {List<Student> findAll();
}

创建映射文件

-- 自定义映射关系
<resultMap id="studentMapper" type="com.yibeigen.pojo.Student"><!-- 主键列 --><id property="sid" column="sid"></id><!-- 普通列 --><result property="name" column="name"></result><result property="age" column="age"></result><result property="sex" column="sex"></result><!-- 一对一对象列 property:属性名  column:关联列名 javaType:对象类型--> 封装<association property="classes" column="classId" javaType="com.yibeigen.pojo.Classes"><!-- 关联对象主键列 --><id property="cid" column="cid"></id><!-- 关联对象普通列 --><result property="className" column="className"></result></association></resultMap><!-- 多表查询,级联查询学生和其班级 -->
<select id="findAll" resultMap="studentMapper">select * from student left join classes on student.classId = classes.cid;
</select>

配置文件注册映射文件

<mappers><package name="com.yibeigen.mapper"/>
</mappers>

测试一对一关联查询

InputStream is = null;
SqlSession session = null;@Before
public void before() throws IOException {is = Resources.getResourceAsStream("SqlMapConfig.xml");SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();SqlSessionFactory factory = builder.build(is);session = factory.openSession();
}@After
public void after() throws IOException {session.close();is.close();
}@Test
public void testFindAllStudent(){StudentMapper studentMapper = session.getMapper(StudentMapper.class);List<Student> all = studentMapper.findAll();all.forEach(System.out::println);
}

3. 一对多关联查询

查询班级时,将关联的学生集合查询出来,就是一对多关联查询
封装:collection

创建持久层接口

public interface ClassesMapper {List<Classes> findAll();
}

创建映射文件

<resultMap id="classesMapper" type="com.itbaizhan.pojo.Classes"><id property="cid" column="cid"></id><result property="className" column="className"></result><!-- 集合列  property:属性名  column:关联列名 ofType:集合的泛型 --><collection property="studentList" column="classId" ofType="com.yibeigen.pojo.Student"><id property="sid" column="sid"></id><result property="name" column="name"></result><result property="age" column="age"></result><result property="sex" column="sex"></result></collection>
</resultMap><!-- 多表查询,级联查询班级和它的学生 -->
<select id="findAll" resultMap="classesMapper">select * from classes left join student  on classes.cid = student.classId;
</select>

测试一对多关联查询

@Test
public void testFindAllClasses() {ClassesMapper classesMapper = session.getMapper(ClassesMapper.class);List<Classes> all = classesMapper.findAll();all.forEach(System.out::println);
}

4. 多对多关联查询

MyBatis多对多关联查询本质就是两个一对多关联查询

例如有老师类和班级类:
一个老师对应多个班级,也就是老师类中有一个班级集合属性
一个班级对应多个老师,也就是班级类中有一个老师集合属性

实体类设计如下:

public class Teacher {private Integer tid;private String tname;private List<Classes> classes;// 省略getter/setter/toString
}public class Classes {private Integer cid;private String className;private List<Student> studentList;private List<Teacher> teacherList;// 省略getter/setter/toString
}

在数据库设计中,需要建立中间表,双方与中间表均为一对多关系

接下来测试查询老师时,将关联的班级集合查询出来

创建持久层接口

public interface TeacherMapper {List<Teacher> findAll();
}

创建映射文件

<resultMap id="teacherMapper" type="com.yibeigen.pojo.Teacher"><id column="tid" property="tid"></id><result column="tname" property="tname"></result><collection property="classes" column="tid" ofType="com.yiebeigen.pojo.Classes"><id column="cid" property="cid"></id><result column="className" property="className"></result></collection>
</resultMap><select id="findAll" resultMap="teacherMapper">select *from teacherleft join classes_teacheron teacher.tid = classes_teacher.tidleft join classeson classes_teacher.cid = classes.cid
</select>

测试多对多关联查询

@Test
public void testFindAllTeacher() {TeacherMapper teacherMapper = session.getMapper(TeacherMapper.class);List<Teacher> all = teacherMapper.findAll();all.forEach(System.out::println);
}

5. 总结

http://www.dtcms.com/a/353864.html

相关文章:

  • Ansible Playbook 概述与实践案例(下)
  • 基于muduo库的图床云共享存储项目(二)
  • STM32 之串口WIFI应用--基于RTOS的环境
  • AlphaFold 2 本地部署与安装教程(Linux)
  • ICCV 2025 | 清华IEDA提出GUAVA,单图创建可驱动的上半身3D化身!实时、高效,还能捕捉细腻的面部表情和手势。
  • 【51单片机】【protues仿真】基于51单片机篮球计时计分器数码管系统
  • 什么是代理ip?代理ip的运作机制
  • C++ 中 ::(作用域解析运算符)的用途
  • 大小鼠糖水偏爱实验系统 糖水偏好实验系统 小鼠糖水偏好实验系统 大鼠糖水偏好实验系统
  • 【半导体制造流程概述】
  • 优化IDEA卡顿的问题
  • 使用CCProxy搭建http/https代理服务器
  • AWS OpenSearch 可观测最佳实践
  • Maya绑定:人物绑定详细案例
  • 数据结构之 【红黑树的简介与插入问题的实现】
  • 数值分析离散积分近似求值
  • 【数据分析】微生物群落网络构建与模块划分的比较研究:SparCC、Spearman-RAW与Spearman-CLR方法的性能评估
  • Shell编程-随机密码生成
  • volitale伪共享问题及解决方案
  • SoC如何实现线程安全?
  • 【进阶篇第五弹】《详解存储过程》从0掌握MySQL中的存储过程以及存储函数
  • TypeScript:Interface接口
  • 如何启动一个分支网络改造试点?三步走
  • 【链表 - LeetCode】25. K 个一组翻转链表
  • 干眼症护理学注意事项
  • linux下的网络编程(2)
  • 技术分析 | Parasoft C/C++test如何突破单元测试的隔离难题
  • 亚马逊关键词策略全解析:类型、工具与多账号运营优化指南
  • AT_abc406_f [ABC406F] Compare Tree Weights
  • Windows/Linux 环境下 Jmeter 性能测试的安装与使用