mybatis关联查询

在 MyBatis 中,关联查询主要用于处理数据库表之间的关系,比如一对一、一对多和多对多的关系。MyBatis 通过 <resultMap> 元素来实现这些复杂的关系映射。

一对一关联

假设我们有两个表:StudentAddress,每个学生有一个地址。下面将使用 MyBatis 来进行一对一关联查询。

实体类
java 复制代码
public class Student {
    private int id;
    private String name;
    private Address address; // 一对一关联

    // getters and setters
}

public class Address {
    private int id;
    private String street;
    private String city;

    // getters and setters
}
Mapper XML 文件
XML 复制代码
<resultMap id="studentResultMap" type="com.gs.entity.Student">
    <id column="student_id" property="id"/>
    <result column="name" property="name"/>
    <!-- 一对一关联 -->
    <association property="address" javaType="com.gs.entity.Address">
        <id column="address_id" property="id"/>
        <result column="street" property="street"/>
        <result column="city" property="city"/>
    </association>
</resultMap>

<select id="selectStudentsWithAddresses" resultMap="studentResultMap">
    SELECT s.id as student_id, s.name, a.id as address_id, a.street, a.city
    FROM student s
    LEFT JOIN address a ON s.address_id = a.id
</select>

一对多关联

假设我们有 Student 表和 Course 表,一个学生可以选修多个课程。下面将使用 MyBatis 来进行一对多关联查询。

实体类
java 复制代码
public class Student {
    private int id;
    private String name;
    private List<Course> courses; // 一对多关联

    // getters and setters
}

public class Course {
    private int id;
    private String name;

    // getters and setters
}
Mapper XML 文件
XML 复制代码
<resultMap id="studentResultMap" type="com.gs.entity.Student">
    <id column="student_id" property="id"/>
    <result column="name" property="name"/>
    <!-- 一对多关联 -->
    <collection property="courses" ofType="com.gs.entity.Course">
        <id column="course_id" property="id"/>
        <result column="course_name" property="name"/>
    </collection>
</resultMap>

<select id="selectStudentsWithCourses" resultMap="studentResultMap">
    SELECT s.id as student_id, s.name, c.id as course_id, c.name as course_name
    FROM student s
    LEFT JOIN student_course sc ON s.id = sc.student_id
    LEFT JOIN course c ON sc.course_id = c.id
</select>

多对多关联

假设我们有 Student 表和 Course 表,学生和课程之间是多对多的关系,通过中间表 student_course 来关联。下面将使用 MyBatis 来进行多对多关联查询。

实体类
java 复制代码
public class Student {
    private int id;
    private String name;
    private List<Course> courses; // 多对多关联

    // getters and setters
}

public class Course {
    private int id;
    private String name;

    // getters and setters
}
Mapper XML 文件
XML 复制代码
<resultMap id="studentResultMap" type="com.gs.entity.Student">
    <id column="student_id" property="id"/>
    <result column="name" property="name"/>
    <!-- 多对多关联 -->
    <collection property="courses" ofType="com.gs.entity.Course">
        <id column="course_id" property="id"/>
        <result column="course_name" property="name"/>
    </collection>
</resultMap>

<select id="selectStudentsWithCourses" resultMap="studentResultMap">
    SELECT s.id as student_id, s.name, c.id as course_id, c.name as course_name
    FROM student s
    LEFT JOIN student_course sc ON s.id = sc.student_id
    LEFT JOIN course c ON sc.course_id = c.id
</select>

注意事项

  • 确保你的实体类中有相应的属性和 getter/setter 方法。
  • <resultMap> 中,<association> 用于一对一关系,<collection> 用于一对多或多对多关系。
  • 使用合适的 SQL 查询语句来连接相关表,并确保列别名与 <resultMap> 中定义的列名一致。
1. 映射关系的定义
  • 正确使用 <association><collection>:

    • <association> 用于一对一的关系。
    • <collection> 用于一对多或多对多的关系。
    • 确保 javaTypeofType 属性设置正确,以匹配你的实体类。
  • 列别名:

    • 在 SQL 查询中使用列别名,并确保这些别名与 <resultMap> 中定义的列名一致。
    • 例如:SELECT s.id as student_id, s.name, a.id as address_id, a.street, a.city FROM student s LEFT JOIN address a ON s.address_id = a.id
2. 性能优化
  • 延迟加载 (Lazy Loading):

    • 使用 fetchType="lazy" 可以避免不必要的数据加载,提高性能。
    • 例如:<association property="address" javaType="com.gs.entity.Address" fetchType="lazy">
    • 注意:懒加载需要适当的配置和环境支持(如 OpenSessionInView 模式)。
  • 分页查询:

    • 对于大数据量的查询,考虑使用分页来减少每次查询的数据量。
    • 可以使用 MyBatis 的分页插件或自定义分页逻辑。
  • 结果缓存:

    • 利用 MyBatis 的二级缓存或第三方缓存(如 Redis)来缓存查询结果,减少数据库访问次数。
3. 复杂查询的处理
  • 联合查询 vs. 多次查询:

    • 考虑是否使用联合查询(JOIN)还是多次查询(N+1 查询问题)。
    • 联合查询可能在某些情况下更高效,但在复杂场景下可能导致 SQL 语句难以维护。
    • 多次查询可以通过 MyBatis 的懒加载机制来优化性能。
  • 嵌套结果映射:

    • 对于复杂的嵌套关系,可以使用嵌套的 <resultMap> 来简化映射。
相关推荐
Justice link几秒前
企业级NoSql数据库Redis集群
数据库·redis·缓存
爱的叹息1 分钟前
主流数据库的存储引擎/存储机制的详细对比分析,涵盖关系型数据库、NoSQL数据库和分布式数据库
数据库·分布式·nosql
程序媛学姐2 分钟前
SpringKafka错误处理:重试机制与死信队列
java·开发语言·spring·kafka
向阳25619 分钟前
SpringBoot+vue前后端分离整合sa-token(无cookie登录态 & 详细的登录流程)
java·vue.js·spring boot·后端·sa-token·springboot·登录流程
XiaoLeisj35 分钟前
【MyBatis】深入解析 MyBatis XML 开发:增删改查操作和方法命名规范、@Param 重命名参数、XML 返回自增主键方法
xml·java·数据库·spring boot·sql·intellij-idea·mybatis
风象南36 分钟前
SpringBoot实现数据库读写分离的3种方案
java·spring boot·后端
振鹏Dong43 分钟前
策略模式——本质是通过Context类来作为中心控制单元,对不同的策略进行调度分配。
java·策略模式
ChinaRainbowSea1 小时前
3. RabbitMQ 的(Hello World) 和 RabbitMQ 的(Work Queues)工作队列
java·分布式·后端·rabbitmq·ruby·java-rabbitmq
雾月551 小时前
LeetCode 914 卡牌分组
java·开发语言·算法·leetcode·职场和发展
melck1 小时前
liunx日志查询常用命令总结
java·服务器·网络