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. 总结

目录
相关文章
|
1月前
|
人工智能
Qwen3.8抢先体验!正式版即将发布并开源!
千问Qwen3.8即将开源,参数达2.4T,进化速度以“天”计,实力媲美Fable 5。预览版Qwen3.8-Max已上线阿里Token Plan等平台,限时优惠:日间Credits低至1折,夜间更优,个人/团队版月付仅35元起!
3648 140
|
1天前
|
人工智能 C语言
二级C语言题解:十进制转其他进制、非素数求和、重复数统计
本文详解三类经典编程题:十进制转任意进制(填空)、非素数求和(修改)与重复数字统计(设计),含完整代码、逐空分析及易错点解析,助你夯实C语言基础。
23 2
二级C语言题解:十进制转其他进制、非素数求和、重复数统计
|
1天前
|
存储 C语言
C语言二级题解:查找字母以及其他字符个数、数字字符串转双精度值、二维数组上下三角区域数据对调
本文详解C语言二级考试三类典型题:统计字母及非字母字符个数、数字字符串转双精度浮点数、二维数组上下三角区域数据对调。含题目解析、错误定位与完整代码,适合备考学生、中职生及编程爱好者提升实战能力。
38 1
C语言二级题解:查找字母以及其他字符个数、数字字符串转双精度值、二维数组上下三角区域数据对调
|
1天前
|
SQL Java 数据库连接
MyBatis 之基础概念与框架原理详解
MyBatis是一款轻量级半自动ORM框架,封装JDBC,让开发者专注SQL编写与业务逻辑;支持XML/注解配置、动态SQL、高级映射,SQL与代码分离,灵活高效,显著提升持久层开发效率。(239字)
29 1
MyBatis 之基础概念与框架原理详解
|
1天前
|
人工智能 前端开发
飞书和豆包合并后的第一个 Agent,真正的底牌不是模型
本文导读 豆包工作接入飞书后,员工可以沿用已有的组织、文档、数据与权限。真正值得关注的不是办公 Agent 又多一个入口,而是企业 AI 的竞争开始转向谁能使用并治理完整的组织上下文。 办公 Agent 最近有一个很明显的变化。 大家已经不满足于让它写文档、做表格、查网页,而是希望它直接进入公司的工
飞书和豆包合并后的第一个 Agent,真正的底牌不是模型
|
1天前
|
Java 测试技术 数据库连接
Maven 之 JUnit 测试体系构建全解析
本文详解Maven工程中JUnit单元测试实践:从pom.xml依赖配置、test目录结构规范,到@Test断言验证、@Before/@After资源管理,涵盖黑/白盒测试原理与结果判定技巧,助力保障Java代码质量。(239字)
25 1
|
1天前
|
存储 人工智能 自然语言处理
阿里云智能体专用型实例解析:把服务器和Token打包,解决AI Agent落地的核心痛点
本文介绍了阿里云轻量应用服务器智能体专用型实例,解析这款专为Agent运行场景重构架构的全新规格族。它打破传统云服务器与Token资源分散采购的模式,将算力、存储、200Mbps免流量带宽与预付费Tokens打包为一体化套餐,内置ANOLISA专属Agent操作系统,可降低30%无效Token消耗,同时兼容OpenAI与Anthropic双协议,支持主流智能体应用一键部署。全系列9款阶梯规格覆盖从个人开发者到中小企业的全场景需求,三档主力套餐享包月5折、包季4.5折优惠,相比分开采购最高可节省68%成本,从根源上消除AI应用部署的环境搭建门槛与账单超支风险。
阿里云智能体专用型实例解析:把服务器和Token打包,解决AI Agent落地的核心痛点
|
1天前
|
SQL 缓存 Java
MyBatis 之配置与映射核心要点解析
本文详解MyBatis核心配置文件(properties、settings、plugins、typeAliases、environments、mappers)与映射文件(resultMap、sql/include、特殊字符处理),助你掌握动态配置、自定义映射及SQL复用技巧。
24 0
MyBatis 之配置与映射核心要点解析
|
1天前
|
SQL Java 数据库连接
MyBatis之数据操作增删改查基础全解
本文详解MyBatis四大核心操作:增删改查及模糊查询。涵盖事务提交、参数绑定(#与$区别)、资源管理及接口-映射规范,并提供完整代码示例与最佳实践,助你快速掌握MyBatis基础应用。(239字)
25 0
MyBatis之数据操作增删改查基础全解

热门文章

最新文章