mybatis 一对多 级联查询
时间: 2024-12-30 19:18:57 浏览: 5
### MyBatis 实现一对多关系级联查询
在 MyBatis 中,实现一对多关系的级联查询主要依赖于 `<association>` 和 `<collection>` 元素。对于一对多的关系,`<collection>` 是用来表示一个实体对象可以拥有多个其他类型的实体对象。
#### 创建数据库结构
假设有一个 `classroom` 表和一个 `student` 表,其中 `classroom` 对应着多个 `student` 记录。这构成了典型的一对多关系模型[^2]。
```sql
CREATE TABLE classroom (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
description TEXT
);
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
grade INT,
class_id INT, -- 外键指向教室ID
FOREIGN KEY (class_id) REFERENCES classroom(id)
);
```
#### 定义 Java 类型映射
为了更好地理解如何处理这些表之间的关系,在Java端也需要定义相应的POJO类:
```java
public class Classroom {
private Integer id;
private String name;
private String description;
// Getters and Setters...
}
public class Student {
private Integer id;
private String name;
private int grade;
// Getters and Setters...
}
```
接着还需要为 Classroom 添加一个集合属性用于存储其下的学生列表:
```java
import java.util.List;
// Inside the Classroom Class
private List<Student> students;
// Getter & Setter for Students list.
```
#### 编写 Mapper 接口与 XML 文件配置
接下来就是编写对应的Mapper接口及其XML文件中的SQL语句了。这里会涉及到两个部分——一个是获取Classroom的信息;另一个是从属于该Classroom的学生们的数据。
##### 单步查询(Eager Loading)
当采用单步查询的方式时,所有的数据会在一次 SQL 查询中被取出,并通过嵌套的结果集来构建最终的对象图谱。
```xml
<!-- resources/mappers/ClassroomMapper.xml -->
<mapper namespace="com.example.mapper.ClassroomMapper">
<!-- Result Map For Mapping The Nested Collection Of Students To A Classroom Object -->
<resultMap type="Classroom" id="classroomResultMapWithStudents">
<id property="id" column="class_id"/>
<result property="name" column="class_name"/>
<result property="description" column="class_description"/>
<!-- One-to-many relationship mapping using collection tag -->
<collection property="students"
ofType="Student"
select="selectStudentsByClassId"
column="{classId=id}">
<id property="id" column="stu_id"/>
<result property="name" column="stu_name"/>
<result property="grade" column="stu_grade"/>
</collection>
</resultMap>
<!-- Query to fetch classrooms along with their associated students -->
<select id="getClassroomsWithStudents" resultMap="classroomResultMapWithStudents">
SELECT c.id AS class_id, c.name AS class_name, c.description as class_description FROM classroom c ORDER BY c.id ASC
</select>
<!-- Subquery used by the above query's collection element -->
<select id="selectStudentsByClassId" parameterType="map" resultType="Student">
SELECT s.id AS stu_id, s.name AS stu_name, s.grade AS stu_grade
FROM student s WHERE s.class_id = #{classId,jdbcType=INTEGER}
</select>
</mapper>
```
上述代码片段展示了如何利用MyBatis 的 `<collection>` 标签来进行一对多关联查询的操作[^4]。
##### 分布式查询(Lazy Loading)
如果希望减少初次加载的时间开销,则可以选择懒加载模式。这种方式下只有当访问特定字段的时候才会触发额外的数据库请求去填充那些尚未初始化的部分。
要启用懒加载功能,可以在全局设置里开启它,也可以针对某个具体的关联单独指定。
```properties
# mybatis-config.xml or application.properties depending on your setup
lazyLoadingEnabled=true
aggressiveLazyLoading=false
```
之后只需简单修改之前的 resultMap 配置即可支持懒加载行为:
```xml
<collection property="students" ofType="Student" select="selectStudentsByClassId" column="id" lazyLoad="true"/>
```
这样就完成了基本的一对多级联查询的功能介绍及其实现方法[^3]。
阅读全文