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

简介: 本文详解MyBatis关联查询:涵盖一对一(association)、一对多(collection)及多对多(本质为两个一对多)的映射配置与实战示例,含实体设计、XML映射、SQL编写及测试代码,助开发者高效处理表间关系。

前言

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

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 teacher
   left join classes_teacher
   on teacher.tid = classes_teacher.tid
   left join classes
   on 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. 总结

目录
相关文章
|
2月前
|
人工智能 自然语言处理 API
LangChain+LangGraph架构拆解:基于复杂AI任务编排与状态管理的大模型应用开发21.4
本文深度解析LangChain与LangGraph两大主流大模型开发框架:LangChain以链式组件封装实现快速入门与轻量应用;LangGraph则通过有向状态图支持分支、循环、多智能体等复杂编排。二者互补协同,构成从Demo到生产级AI应用的完整技术栈。
207 2
|
3月前
|
人工智能
Qwen3.8抢先体验!正式版即将发布并开源!
千问Qwen3.8即将开源,参数达2.4T,进化速度以“天”计,实力媲美Fable 5。预览版Qwen3.8-Max已上线阿里Token Plan等平台,限时优惠:日间Credits低至1折,夜间更优,个人/团队版月付仅35元起!
5072 158
|
2月前
|
Java 程序员 应用服务中间件
Maven之初识与安装
本文详解Maven安装与配置全流程:从基础概念、下载安装、环境变量配置到版本验证,助新手一次理清逻辑、顺利完成部署;涵盖一键构建、依赖管理核心功能,并提供交流支持。
190 0
Maven之初识与安装
阿里云轻量应用服务器68元/年,新用户特价,不要退款,重新买价格459元,涨价了!
阿里云轻量应用服务器新用户专享价68元/年(2核2G、200M带宽、40GB ESSD),秒杀低至38元。⚠️地域选定后不可修改,退款将失去新用户资格,再购恢复原价459元/年!务必下单前确认地域,避免浪费优惠。阿里云轻量应用服务器官网:https://t.aliyun.com/U/dwftch
|
2月前
|
人工智能 安全 中间件
AI 帮你改了 20 个文件,最后 3 个忘了改——长任务为什么总是"差一口气"?
AI长任务常因“失忆”、误删、静默跳过、截断编造等问题翻车。UseIO通过Plan驱动拆解、检查点回滚、三级安全门控、结构化错误处理与交付前四点复查,构建工程级可靠性防护链,显著提升多文件重构等复杂任务的完成率与稳定性。(239字)
|
2月前
|
人工智能 JSON 自然语言处理
Vibe Coding实战:从零构建网页3D交互角色
本文详解Vibe Coding(氛围编程)在网页3D开发中的实践:以“2D→3D→网页”标准化流程为核心,结合腾讯混元3D生成高质量可动画模型,再用Three.js嵌入GLB文件实现交互式渲染,并提供完整代码、提示词模板及八大常见坑点解决方案,助力零基础快速落地3D网页应用。
283 0
Vibe Coding实战:从零构建网页3D交互角色
|
2月前
|
缓存 人工智能 计算机视觉
Qwen3.8-Flash模型介绍:能力、上下文限制、费用定价详细说明
通义千问最新多模态大模型Qwen3.8-Flash(ID:qwen3.8-flash),原生支持百万级上下文(100万tokens)、文本/图像/视频输入,输出为文本。具备Function Calling、结构化输出、联网搜索(限北京/新加坡)等能力,兼容OpenAI/Anthropic协议,已在阿里云百炼平台开放免费试用(赠100万Tokens)。在阿里云百炼官网:https://t.aliyun.com/U/fPVHqY 免费领取千万Tokens
|
2月前
|
缓存 测试技术 API
大模型API中转站避坑:满血验证、倍率换算与降智识别(附压测代码)
从工程师视角系统梳理大模型API中转站的评估方法:讲清兑换比例与倍率的真实换算关系,给出满血模型验证三招(复杂推理压测、模型指认、长上下文压力测试)与可运行的Python压测脚本,并总结稳定性、协议兼容、计费透明等接入要点和先测后充的避坑建议。
|
2月前
|
存储 C语言
二级C语言题解:整数序列奇偶个数、拼接数字字符、数组取偶数并加小数点
本文详解C语言三道经典编程题:①统计整数序列中奇偶数个数并返回结构体;②提取字符串中数字字符拼接成整数;③筛选数组偶数并按原序拼接为“数字.”格式字符串。含完整代码、填空/修改/设计解析及易错点提醒。
105 1
二级C语言题解:整数序列奇偶个数、拼接数字字符、数组取偶数并加小数点
|
2月前
|
前端开发 Java 测试技术
Maven 之工程构建与依赖管理全攻略
本文系统讲解Maven核心知识:涵盖POM/JAR/WAR工程类型与标准目录结构;详解构建生命周期(validate→compile→test→package→install→deploy)及常用命令;深入解析本地/远程/中央仓库机制,并指导配置本地仓库路径、阿里云镜像及JDK版本。内容精炼实用,助开发者快速掌握Maven项目管理精髓。
145 1
Maven 之工程构建与依赖管理全攻略

热门文章

最新文章