MyBatis 一对多与多对一映射详解教程


一、基础概念与场景

  1. 一对多(One-to-Many)
    • 定义:一个父对象包含多个子对象。

例如:一个商品(Goods)对应多个商品详情(GoodsDetail)
• 实体类表现:父类中包含 List<子类> 属性。

// Goods.java
public class Goods {private List<GoodsDetail> goodsDetails; // 一对多关系
}
  1. 多对一(Many-to-One)
    • 定义:多个子对象属于一个父对象。

例如:多个商品详情(GoodsDetail)属于一个商品(Goods)
• 实体类表现:子类中包含父类对象属性。

// GoodsDetail.java
public class GoodsDetail {private Goods goods; // 多对一关系
}

二、XML配置实现

  1. 一对多映射(父→子)
    使用 <collection> 标签,核心配置如下:
<!-- GoodsMapper.xml -->
<resultMap id="rmGoods1" type="Goods"><id column="goods_id" property="goodsId"/><!-- 一对多:通过子查询获取商品详情 --><collection property="goodsDetails" select="goodsDetail.selectByGoodsId" column="goods_id"/>
</resultMap><select id="selectOneToMany" resultMap="rmGoods1">SELECT * FROM t_goods LIMIT 0,10
</select>

• 参数解释:

select:指向子查询的命名空间(如 goodsDetail.selectByGoodsId

column:传递父查询结果中的字段值(如 goods_id)到子查询


  1. 多对一映射(子→父)
    使用 <association> 标签,核心配置如下:
<!-- GoodsDetailMapper.xml -->
<resultMap id="rmGoodsDetail" type="GoodsDetail"><id column="gd_id" property="gdId"/><!-- 多对一:通过父查询获取商品信息 --><association property="goods" select="goods.selectById" column="goods_id"/>
</resultMap><select id="selectManyToOne" resultMap="rmGoodsDetail">SELECT * FROM t_goods_detail LIMIT 0,1
</select>

• 参数解释:

select:指向父查询的命名空间(如 goods.selectById

column:传递当前表的字段值(如 goods_id)到父查询


三、联表查询优化

  1. 一对多联表查询(避免N+1问题)
    直接通过JOIN查询一次性获取父子数据:
<resultMap id="rmGoodsJoin" type="Goods"><collection property="goodsDetails" ofType="GoodsDetail"><id column="gd_id" property="gdId"/><result column="gd_pic_url" property="gdPicUrl"/></collection>
</resultMap><select id="selectJoin" resultMap="rmGoodsJoin">SELECT g.*, d.* FROM t_goods g LEFT JOIN t_goods_detail d ON g.goods_id = d.goods_id
</select>

• 优点:减少数据库查询次数,提升性能


  1. 多对一联表查询
<resultMap id="rmDetailJoin" type="GoodsDetail"><association property="goods" javaType="Goods"><id column="goods_id" property="goodsId"/><result column="title" property="title"/></association>
</resultMap><select id="selectDetailWithGoods" resultMap="rmDetailJoin">SELECT d.*, g.title FROM t_goods_detail d INNER JOIN t_goods g ON d.goods_id = g.goods_id
</select>

四、常见问题与解决方案

  1. N+1查询问题
    • 现象:父查询返回N条数据,触发N次子查询,导致性能低下。

• 解决:

• 开启懒加载:在 mybatis-config.xml 中配置:

```xml
<settings><setting name="lazyLoadingEnabled" value="true"/>
</settings>
```

• 使用联表查询(如上述第三节)


  1. 字段名冲突
    • 现象:联表查询时多个表有相同字段名(如 id)。

• 解决:

• 使用别名区分字段:

```sql
SELECT g.id AS goods_id, d.id AS detail_id
```

• 在 <resultMap> 中明确指定映射关系


五、最佳实践总结

场景推荐方案适用场景
数据量小分步查询(<collection>/<association>字段关联逻辑简单
数据量大联表查询需要一次性获取完整数据
实时性要求高联表查询 + 缓存高频读取场景
更新频繁分步查询 + 懒加载减少无效数据加载

学习建议:

  1. 从简单分步查询入手,理解映射逻辑
  2. 逐步尝试联表查询,对比性能差异
  3. 参考官方文档中的 <resultMap> 高级用法
  4. 通过单元测试验证结果集映射(如 System.out.println(goods.getGoodsDetails().size())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/904235.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT:重塑人工智能交互范式的破晓之作

2022年11月30日,总部位于旧金山的研究公司OpenAI正式发布了ChatGPT——一款以病毒式传播速度席卷全球的AI聊天机器人。它不仅能像人类一样生成内容、回答问题和解决问题,更在推出后的两个月内吸引了超过1亿月活跃用户,刷新了消费级技术应用的最快采用率纪录。这一里程碑事件…

在项目中如何对Map List等对象序列化及反序列化

我们知道&#xff0c;在自定义类中&#xff0c;若想完成序列化必须要实现Serializable接口。 那么在实现后如何进行序列化呢&#xff1f; 一.普通对象 序列化&#xff1a; 1.首先我们要定义一个 序列化所需要的工具类 ObjectMapper //定义序列化所需要的工具类 转化机器…

笔试专题(十五)

文章目录 排序子序列题解代码 消减整数题解代码 最长公共子序列(二)题解代码 排序子序列 题目链接 题解 1. 贪心 模拟 2. 1 2 3 2 2 应该是有两个排列子序列的&#xff0c;所以i n-1时ret 3. 把水平的位置和上升部分&#xff0c;水平位置和下降部分分为一个排列子序列 代…

Amazon Bedrock Converse API:开启对话式AI新体验

Amazon Bedrock Converse API&#xff1a;开启对话式AI新体验 前言 在当今人工智能飞速发展的时代&#xff0c;对话式AI已成为众多应用的核心组成部分。从智能客服到智能助手&#xff0c;对话式AI为用户带来了便捷且高效的交互体验。而Amazon Bedrock Converse API的出现&…

【Springboot知识】Springboot计划任务Schedule详解

文章目录 Spring Boot 定时任务从原理到实现详解一、核心原理分析1. 架构分层2. 核心组件3. 线程模型 二、基础实现步骤1. 添加依赖2. 主类配置3. 定时任务类 三、高级配置技巧1. 自定义线程池2. 动态配置参数3. 分布式锁集成&#xff08;Redis示例&#xff09; 四、异常处理机…

MySQL:联合查询

目录 一、笛卡尔积 ​二、内连接 三、外连接 &#xff08;1&#xff09;左外连接 &#xff08;2&#xff09;右外连接 &#xff08;3&#xff09;全外连接 四、自连接 五、子查询 &#xff08;1&#xff09;单行子查询 &#xff08;2&#xff09;多行子查询 &…

深入理解 Cortex-M3 的内核寄存器组

每个 MCU 开发工程师一定都了解寄存器这个东西&#xff0c;以 STM32 为例&#xff0c;其拥有非常多的外设模块&#xff0c;如串口、SPI、IIC 等等&#xff0c;如果要使用这些外设&#xff0c;使其按照我们的要求工作&#xff0c;就需要配置这些外设的寄存器&#xff0c;往这些寄…

网络安全自动化:找准边界才能筑牢安全防线

数字时代&#xff0c;企业每天要面对成千上万的网络攻击。面对庞大的服务器群、分散的团队和长期不重启的设备&#xff0c;很多企业开始思考&#xff1a;哪些安全操作适合交给机器自动处理&#xff1f;哪些必须由人工把关&#xff1f;今天我们就用大白话聊聊这件事。 一、这些事…

C++负载均衡远程调用学习之负载均衡算法与实现

目录 01 lars 系统架构回顾 02 lars-lbAgentV0.4-route_lb处理report业务流程 03 lars-lbAgentV0.4-负责均衡判断参数配置 04 lars-lbAgentV0.4-负载均衡idle节点的失败率判断 05 lars-lbAgentV0.4-负载均衡overload节点的成功率判断 06 lars-lbAgentV0.4-负载均衡上报提交…

领略算法真谛: 多源bfs

嘿&#xff0c;各位技术潮人&#xff01;好久不见甚是想念。生活就像一场奇妙冒险&#xff0c;而编程就是那把超酷的万能钥匙。此刻&#xff0c;阳光洒在键盘上&#xff0c;灵感在指尖跳跃&#xff0c;让我们抛开一切束缚&#xff0c;给平淡日子加点料&#xff0c;注入满满的pa…

雷电模拟器-超好用的Windows安卓模拟器

一、雷电模拟器介绍 雷电模拟器是一款功能强大的软件&#xff0c;它能够在电脑上模拟出安卓手机系统&#xff0c;让你可以在电脑上运行各类手机应用及游戏。其采用虚拟安卓手机操作界面&#xff0c;为玩家带来了独特的体验。 &#xff08;一&#xff09;强大的兼容性 雷电模拟…

文章三《机器学习基础概念与框架实践》

文章3:机器学习基础概念与框架实践 ——从理论到代码,用Scikit-learn构建你的第一个分类模型 一、机器学习基础理论:三大核心类型 机器学习是人工智能的核心,通过数据让计算机自动学习规律并做出预测或决策。根据学习方式,可分为三类: 1. 监督学习(Supervised Learni…

脑机接口技术:开启人类与机器的全新交互时代

在科技飞速发展的今天&#xff0c;人类与机器的交互方式正经历着前所未有的变革。从最初的键盘鼠标&#xff0c;到触摸屏&#xff0c;再到语音控制&#xff0c;每一次交互方式的升级都极大地提升了用户体验和效率。如今&#xff0c;脑机接口&#xff08;Brain-Computer Interfa…

8.2 GitHub企业级PDF报告生成实战:ReportLab高级技巧与性能优化全解析

GitHub企业级PDF报告生成实战:ReportLab高级技巧与性能优化全解析 GitHub Sentinel 高级功能实现:PDF 报告生成技术详解 关键词:PDF 报告生成, ReportLab 实战, 结构化数据转换, 容器化字体配置, 企业级报告模板 1. 需求分析与技术选型 PDF 报告生成需要满足以下技术要求…

架构思维:构建高并发读服务_基于流量回放实现读服务的自动化测试回归方案

文章目录 引言一、升级读服务架构&#xff0c;为什么需要自动化测试&#xff1f;二、自动化回归测试系统&#xff1a;整体架构概览三、日志收集1. 拦截方式2. 存储与优化策略3. 架构进化 四、数据回放技术实现关键能力 五、差异对比对比方式灵活配置 六、三种回放模式详解1. 离…

基于Spring Boot 3.0、ShardingSphere、PostgreSQL或达梦数据库的分库分表

要实现基于Spring Boot 3.0、ShardingSphere、PostgreSQL或达梦数据库的分库分表&#xff0c;首先需要对ShardingSphere进行一些基本配置。你提到的溯源码、批次号等数据需要考虑到跨年数据的存储&#xff0c;因此要设计一个能够动态扩展的分表策略 添加ShardingSphere依赖 在…

位运算的应用

1. 判断偶数&#xff0c;判断最低位是0还是1即可&#xff0c;⽐求模快 x % 2 ! 0 //x正负都可以判断&#xff1b;不⽤x%2 1&#xff0c;因为如果x为负奇数&#xff0c;x%2-1 (x & 0x1) 0 例如&#xff1a; int x; int main() { cin>>x; if((x & 0x1)0) cout<…

FOC算法开环控制基础

1. 为什么要有FOC算法 先看看从有刷电机到无刷电机的简单介绍&#xff0c;如下图1&#xff0c;通电螺线圈会产生磁场&#xff0c;这个磁场会产生N级和S级&#xff0c;然后这个电磁铁就可以吸引永磁体&#xff0c;S级吸引N级&#xff0c;N级吸引S级&#xff0c;通俗的来说&…

【计算机网络】HTTP中GET和POST的区别是什么?

从以下几个方面去说明&#xff1a; 1.定义 2.参数传递方式 3.安全性 4.幂等性 1.定义&#xff1a; GET&#xff1a; 获取资源&#xff0c;通常请求数据而不改变服务器的状态。POST&#xff1a; 提交数据到服务器&#xff0c;通常会改变服务器的状态或副作用(如创建或更新资源…

7400MB/s5050TBW完美结合,全新希捷酷玩530R SSD体验评测

7400MB/s&5050TBW完美结合&#xff0c;全新希捷酷玩530R SSD体验评测 哈喽小伙伴们好&#xff0c;我是Stark-C~ 说到希捷酷玩530 SSD&#xff0c;很多硬核进阶玩家应该都知道&#xff0c;或者说正在使用&#xff08;比如说我~&#xff09;。 作为希捷大厂旗下高性能SSD的…