MyBatis一对多查询方式

在 MyBatis 中,一对多查询是指一个实体对象(如 Order)关联多个子对象(如 OrderItem)。这种关系在数据库中通常通过外键实现,而在 MyBatis 中可以通过 resultMap 的嵌套集合(<collection>)来处理。

以下是对 MyBatis 中一对多查询的详细介绍,包括实现步骤和示例代码。


1. 一对多关系的数据表设计

假设我们有两个表:

  • Orders:存储订单信息。
  • OrderItems:存储订单项信息,每个订单项属于一个订单。

表结构如下:

CREATE TABLE Orders (order_id INT PRIMARY KEY,order_number VARCHAR(50),customer_id INT,order_date DATE
);CREATE TABLE OrderItems (item_id INT PRIMARY KEY,order_id INT,product_name VARCHAR(100),quantity INT,price DECIMAL(10, 2),FOREIGN KEY (order_id) REFERENCES Orders(order_id)
);
  • 一个订单(Orders)可以包含多个订单项(OrderItems)。
  • OrderItems 表中的 order_id 是外键,指向 Orders 表的 order_id

2. 实体类设计

在 Java 中,我们需要定义两个实体类来表示这种一对多关系。

Order

public class Order {private int orderId;private String orderNumber;private int customerId;private Date orderDate;private List<OrderItem> orderItems; // 一对多关系// Getters and Setters
}

OrderItem

public class OrderItem {private int itemId;private int orderId;private String productName;private int quantity;private BigDecimal price;// Getters and Setters
}

3. MyBatis 实现一对多查询

在 MyBatis 中,一对多查询通常通过 resultMap<collection> 标签来实现。以下是具体步骤。

3.1 定义 resultMap

在 MyBatis 的 Mapper XML 文件中,定义一个 resultMap,使用 <collection> 标签来表示一对多关系。

<resultMap id="OrderResultMap" type="Order"><!-- 映射 Order 表的基本字段 --><id property="orderId" column="order_id"/><result property="orderNumber" column="order_number"/><result property="customerId" column="customer_id"/><result property="orderDate" column="order_date"/><!-- 一对多关系:Order 包含多个 OrderItem --><collection property="orderItems" ofType="OrderItem"><id property="itemId" column="item_id"/><result property="orderId" column="order_id"/><result property="productName" column="product_name"/><result property="quantity" column="quantity"/><result property="price" column="price"/></collection>
</resultMap>
  • property="orderItems":对应 Order 类中的 orderItems 属性。
  • ofType="OrderItem":表示集合中的元素类型是 OrderItem

3.2 编写 SQL 查询

使用 LEFT JOINOrders 表和 OrderItems 表连接起来,确保即使某个订单没有订单项,也能查询到订单信息。

<select id="getOrderWithItems" resultMap="OrderResultMap">SELECT o.order_id, o.order_number, o.customer_id, o.order_date,i.item_id, i.product_name, i.quantity, i.priceFROM Orders oLEFT JOIN OrderItems i ON o.order_id = i.order_idWHERE o.order_id = #{orderId}
</select>
  • 使用 LEFT JOIN 是为了确保即使某个订单没有订单项,也能返回订单信息。
  • #{orderId} 是传入的参数。

3.3 Java 接口

在 Java 接口中定义方法:

public interface OrderMapper {Order getOrderWithItems(@Param("orderId") int orderId);
}

4. 查询结果

假设数据库中有以下数据:

Orders

order_idorder_numbercustomer_idorder_date
1ORDER0011012023-10-01
2ORDER0021022023-10-02

OrderItems

item_idorder_idproduct_namequantityprice
11Product A2100.00
21Product B150.00
32Product C3200.00

调用 getOrderWithItems(1) 后,返回的 Order 对象如下:

Order {orderId: 1,orderNumber: "ORDER001",customerId: 101,orderDate: "2023-10-01",orderItems: [OrderItem {itemId: 1,orderId: 1,productName: "Product A",quantity: 2,price: 100.00},OrderItem {itemId: 2,orderId: 1,productName: "Product B",quantity: 1,price: 50.00}]
}

5. 一对多查询的优化

如果查询结果较大,可能会产生性能问题(如 N+1 查询问题)。可以通过以下方式优化:

5.1 使用 LEFT JOIN 一次性加载

如上面的示例,使用 LEFT JOIN 一次性加载所有数据,避免多次查询。

5.2 分步查询

如果数据量较大,可以使用分步查询(嵌套查询):

<resultMap id="OrderResultMap" type="Order"><id property="orderId" column="order_id"/><result property="orderNumber" column="order_number"/><result property="customerId" column="customer_id"/><result property="orderDate" column="order_date"/><!-- 分步查询:通过 order_id 查询 OrderItems --><collection property="orderItems" ofType="OrderItem" select="selectOrderItemsByOrderId" column="order_id"/>
</resultMap><select id="selectOrderItemsByOrderId" resultType="OrderItem">SELECT item_id, order_id, product_name, quantity, priceFROM OrderItemsWHERE order_id = #{orderId}
</select><select id="getOrderWithItems" resultMap="OrderResultMap">SELECT order_id, order_number, customer_id, order_dateFROM OrdersWHERE order_id = #{orderId}
</select>
  • select="selectOrderItemsByOrderId":指定嵌套查询的方法。
  • column="order_id":将当前查询的 order_id 作为参数传递给嵌套查询。

6. 总结

  • 一对多查询在 MyBatis 中通过 <collection> 标签实现。
  • 可以使用 LEFT JOIN 一次性加载数据,也可以使用分步查询优化性能。
  • 确保实体类和数据库表的结构正确映射。
  • 通过 resultMap 可以灵活地处理复杂的对象关系。

通过以上方法,你可以在 MyBatis 中轻松实现一对多查询,并灵活应对不同的业务需求。

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

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

相关文章

C语言基础知识04

指针 指针概念 指针保存地址&#xff0c;地址是字节的编号 指针类型和保存的地址类型要一直 使用时注意&#xff0c;把地址转换为&变量的格式来看 int a[3]; a转为&a[0] 指针的大小 64bit 固定8字节&#xff0c; 32bit 固定4字节 指针…

IDEA 一键完成:打包 + 推送 + 部署docker镜像

1、本方案要解决场景&#xff1f; 想直接通过本地 IDEA 将最新的代码部署到远程服务器上。 2、本方案适用于什么样的项目&#xff1f; 项目是一个 Spring Boot 的 Java 项目。项目用 maven 进行管理。项目的运行基于 docker 容器&#xff08;即项目将被打成 docker image&am…

浏览器崩溃的第一性原理:内存管理的艺术

作者&#xff1a;京东科技 屠永涛 登录后复制 你是否曾经遇到过浏览器突然卡顿&#xff0c;甚至崩溃的情况&#xff1f;尤其是在打开多个标签页或运行复杂的网页应用时&#xff0c;浏览器似乎变得异常脆弱。这种崩溃的背后&#xff0c;往往与内存管理息息相关。 1. 浏览器的内存…

Redis的缓存雪崩、缓存击穿、缓存穿透与缓存预热、缓存降级

一、缓存雪崩&#xff1a; 1、什么是缓存雪崩&#xff1a; 如果缓在某一个时刻出现大规模的key失效&#xff0c;那么就会导致大量的请求打在了数据库上面&#xff0c;导致数据库压力巨大&#xff0c;如果在高并发的情况下&#xff0c;可能瞬间就会导致数据库宕机。这时候如果…

算法刷题整理合集(一)

本篇博客旨在记录自已的算法刷题练习成长&#xff0c;里面注有详细的代码注释以及和个人的思路想法&#xff0c;希望可以给同道之人些许帮助。本人也是算法小白&#xff0c;水平有限&#xff0c;如果文章中有什么错误或遗漏之处&#xff0c;望各位可以在评论区指正出来&#xf…

ubuntu ollama+dify实践

安装ollama 官网的指令太慢了&#xff0c;使用以下指令加速&#xff1a; export OLLAMA_MIRROR"https://ghproxy.cn/https://github.com/ollama/ollama/releases/latest/download" curl -fsSL https://ollama.com/install.sh | sed "s|https://ollama.com/dow…

Cookie与Session详解

Cookie简介 Cookie 是浏览器提供的持久化存储数据的一种机制。是指某些网站为了辨别用户身份、进行会话跟踪而储存在用户本地终端上的数据&#xff08;通常经过加密&#xff09;。以下是关于 Cookie 的详细介绍&#xff1a; Cookie工作原理 当你访问一个网站时&#xff0c;该网…

Python Openpyxl给Excel增加条件规则

使用openpyxl添加条件格式是一个简单而直接的过程。在使用Excel文件时&#xff0c;条件格式对于数据趋势的可视化、突出显示关键数据点以及使数据更有意义和可理解非常有用。在本文中&#xff0c;我们将详细介绍如何使用openpyxl添加条件格式。 OpenPyxl中的条件格式简介 在进…

离线服务器ollama新增qwen2:0.5b模型

离线服务器ollama新增qwen2:0.5b模型 Dify集成ollama前面已经介绍过离线服务器CentOS使用的docker安装的ollama&#xff0c;其中在ollama中已经安装了deepseek-r1:1.5b。目前的需求是需要再安装一个qwen2:0.5b的模型&#xff0c;那么如何安装呢&#xff1f; 1.首先在有网的服…

零成本本地化搭建开源AI神器LocalAI支持CPU推理运行部署方案

文章目录 前言1. Docker部署2. 简单使用演示3. 安装cpolar内网穿透4. 配置公网地址5. 配置固定公网地址 前言 嘿&#xff0c;小伙伴们&#xff01;今天给大家带来一个超酷的黑科技——LocalAI。没错&#xff0c;你没听错&#xff0c;就是那个能在你的个人电脑上运行大型语言模…

数据类设计_图片类设计之4_规则类图形混合算法(前端架构)

前言 学的东西多了,要想办法用出来.C和C是偏向底层的语言,直接与数据打交道.尝试做一些和数据方面相关的内容 引入 接续上一篇,讨论图片类型设计出来后在场景中如何表达,以及图片的混合算法.前面的内容属于铺垫和基础,这篇内容和实际联系起来了. 背景图和前景图 这里笔者想先…

Burpsuite使用笔记

Burpsuite使用笔记 抓包设置代理open Browserintercept on输入要抓包的网站回车ForwardHTTP history查看抓包数据其他浏览器配置burpsuite代理浏览器代理器插件配置打开代理同样步骤访问 原理三级目录 抓包 设置代理 open Browser 打开内置浏览器 intercept on 输入要抓包…

使用Dockerfile打包java项目生成镜像部署到Linux_java项目打docker镜像的dockerfile

比起容器、镜像来说&#xff0c;Dockerfile 非常普通&#xff0c;它就是一个纯文本&#xff0c;里面记录了一系列的构建指令&#xff0c;比如选择基础镜像、拷贝文件、运行脚本等等&#xff0c;每个指令都会生成一个 Layer&#xff0c;而 Docker 顺序执行这个文件里的所有步骤&…

移远通信联合德壹发布全球首款搭载端侧大模型的AI具身理疗机器人

在汹涌澎湃的人工智能浪潮中&#xff0c;具身智能正从实验室构想迈向现实应用。移远通信凭借突破性的端侧AI整体解决方案&#xff0c;为AI机器人强势赋能&#xff0c;助力其实现跨行业拓展&#xff0c;从工业制造到服务接待&#xff0c;再到医疗康养&#xff0c;不断改写各行业…

技术视界|构建理想仿真平台,加速机器人智能化落地

在近期的 OpenLoong 线下技术分享会 上&#xff0c;松应科技联合创始人张小波进行了精彩的演讲&#xff0c;深入探讨了仿真技术在机器人智能化发展中的关键作用。他结合行业趋势&#xff0c;剖析了现有仿真平台的挑战&#xff0c;并描绘了未来理想仿真系统的设计理念与实现路径…

JConsole 在 Linux 上的使用

JConsole 在 Linux 上的使用指南 1. 启动 JConsole 远程监控 Linux 服务器上的 JVM 进程 1.1 修改 JMX 配置&#xff0c;允许远程访问 在 Linux 服务器 启动 Java 应用时&#xff0c;需要加上 -Djava.rmi.server.hostname<服务器IP>&#xff0c;完整的启动参数如下&am…

【C#学习】协程等待

来源GPT&#xff0c;仅记录学习 yield return WaitForEndOfFrame() 适用于 渲染结束后再执行代码&#xff0c;但 WebGL 可能不适合这个操作&#xff0c;会拖慢帧率。(渲染得太慢&#xff09; yield return null; 让代码在下一帧的 Update() 里继续运行&#xff0c;更加流畅。 …

店匠科技携手 PayPal 升级支付体验,助力独立站商家实现全球增长

在全球化电商竞争加剧的背景下,独立站为无数商户插上了通向事业成功的翅膀。然而,搭建店铺框架容易,真正实现有效运营却充满挑战。只有当各个环节如齿轮般严丝合缝,独立站运营才能更好地助推行进,实现稳健增长。如今,独立站商家面临着全链路运营的多重挑战。从品牌塑造、营销推…

【算法】数组、链表、栈、队列、树

⭐️个人主页&#xff1a;小羊 ⭐️所属专栏&#xff1a;Linux 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 持续更新中...数组、链表点击消除环形链表环形链表 II 栈、队列树 持续更新中… 数组、链表 点击消除 AB5 点击消除 这个题很容…

机器学习实战——音乐流派分类(主页有源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ ​​​ 1. 简介 音乐流派分类是音乐信息检索&#xff08;Music Information Retrieval, MIR&#xff09;中的一个重要任务&#xff0c;旨在…