MyBatis关联查询实战:一对一与一对多详细解析

MyBatis关联查询实战:一对一与一对多详细解析

在这里插入图片描述

MyBatis是一款强大的持久层框架,提供了多种方式来处理关联查询,其中包括一对一和一对多的情况。在本文中,我们将深入探讨这两种关联查询的实现方式,并通过具体的示例代码进行详细解释。

一对一关联查询

实现一对一关联查询的方式有多种,其中包括嵌套查询(Nested Queries)和结果集嵌套映射(Result Map With Association)。

1. 嵌套查询(Nested Queries)

嵌套查询是通过在 SQL 查询中嵌套另一条查询,将关联的对象查询出来。这通常通过 <select> 元素嵌套在 <resultMap> 中实现。

1.1 数据库表结构

假设有两个表:usersaddresses,分别存储用户信息和地址信息。

CREATE TABLE users (id INT PRIMARY KEY,username VARCHAR(50),address_id INT
);CREATE TABLE addresses (id INT PRIMARY KEY,city VARCHAR(50),country VARCHAR(50)
);
1.2 MyBatis 映射配置
<!-- User 实体类 -->
<resultMap id="userMap" type="User"><id property="id" column="id" /><result property="username" column="username" /><association property="address" javaType="Address"><id property="id" column="address_id" /><result property="city" column="city" /><result property="country" column="country" /></association>
</resultMap><!-- 查询用户信息的 SQL -->
<select id="selectUser" resultMap="userMap">SELECT u.id, u.username, a.id as address_id, a.city, a.countryFROM users uJOIN addresses a ON u.address_id = a.idWHERE u.id = #{userId}
</select>
1.3 Java 实体类
public class User {private int id;private String username;private Address address;// Getters and setters
}public class Address {private int id;private String city;private String country;// Getters and setters
}
1.4 使用方式
User user = userMapper.selectUser(1);
System.out.println(user.getUsername());
System.out.println(user.getAddress().getCity());
System.out.println(user.getAddress().getCountry());

2. 结果集嵌套映射(Result Map With Association)

另一种方式是使用 association 元素在 <resultMap> 中创建结果集嵌套映射。

2.1 MyBatis 映射配置
<!-- User 实体类 -->
<resultMap id="userMap" type="User"><id property="id" column="id" /><result property="username" column="username" /><association property="address" resultMap="addressMap" />
</resultMap><!-- Address 实体类 -->
<resultMap id="addressMap" type="Address"><id property="id" column="address_id" /><result property="city" column="city" /><result property="country" column="country" />
</resultMap><!-- 查询用户信息的 SQL -->
<select id="selectUser" resultMap="userMap">SELECT u.id, u.username, a.id as address_id, a.city, a.countryFROM users uJOIN addresses a ON u.address_id = a.idWHERE u.id = #{userId}
</select>
2.2 使用方式
User user = userMapper.selectUser(1);
System.out.println(user.getUsername());
System.out.println(user.getAddress().getCity());
System.out.println(user.getAddress().getCountry());

一对多关联查询

实现一对多关联查询的方式也有多种,其中包括嵌套查询(Nested Queries)、嵌套结果集(Nested Result Maps)、集合嵌套映射(Collection Nesting)、以及通过 MyBatis 提供的 collection 元素进行嵌套映射。

1. 嵌套查询(Nested Queries)

嵌套查询是通过在 SQL 查询中嵌套另一条查询,将关联的对象集合查询出来。这通常通过 <select> 元素嵌套在 <resultMap> 中实现。

1.1 数据库表结构

假设有两个表:usersorders,分别存储用户信息和订单信息。

CREATE TABLE users (id INT PRIMARY KEY,username VARCHAR(50)
);CREATE TABLE orders (id INT PRIMARY KEY,user_id INT,order_name VARCHAR(50)
);
1.2 MyBatis 映射配置
<!-- User 实体类 -->
<resultMap id="userMap" type="User"><id property="id" column="id" /><result property="username" column="username" /><collection property="orders" ofType="Order" select="selectOrdersByUserId"/>
</resultMap><!-- Order 实体类 -->
<resultMap id="orderMap" type="Order"><id property="id" column="id" /><result property="orderName" column="order_name" />
</resultMap><!-- 查询用户信息的 SQL -->
<select id="selectUser" resultMap="userMap">SELECT u.id, u.usernameFROM users uWHERE u.id = #{userId}
</select><!-- 查询用户订单的 SQL -->
<select id="selectOrdersByUserId" resultMap="orderMap">SELECT o.id, o.order_nameFROM orders oWHERE o.user_id = #{userId}
</select>
1.3 Java 实体类
public class User {private int id;private String username;private List<Order> orders;// Getters and setters
}public class Order {private int id;private String orderName;// Getters and setters
}
1.4 使用方式
User user = userMapper.selectUser(1);
System.out.println(user.getUsername());for (Order order : user.getOrders()) {System.out.println(order.getOrderName());
}

2. 集合嵌套映射(Collection Nesting)

集合嵌套映射是通过在 <resultMap> 中使用 <collection> 元素进行嵌套映射。

2.1 MyBatis 映射配置
<!-- User 实体类 -->
<resultMap id="userMap" type="User"><id property="id" column="id" /><result property="username" column="username" /><collection property="orders" ofType="Order"><result property="id" column="id" /><result property="orderName" column="order_name" /></collection>
</resultMap><!-- 查询用户信息的 SQL -->
<select id="selectUser" resultMap="userMap">SELECT u.id, u.username, o.id, o.order_nameFROM users uLEFT JOIN orders o ON u.id = o.user_idWHERE u.id = #{userId}
</select>
2.2 使用方式
User user = userMapper.selectUser(1);
System.out.println(user.getUsername());for (Order order : user.getOrders()) {System.out.println(order.getOrderName());
}

3. 使用 collection 元素进行嵌套映射

MyBatis 提供了 collection 元素,可以直接在 <resultMap> 中使用,简化配置。

3.1 MyBatis 映射配置
<!-- User 实体类 -->
<resultMap id="userMap" type="User"><id property="id" column="id" /><result property="username" column="username" /><collection property="orders" ofType="Order" column="user_id" select="selectOrdersByUserId"/>
</resultMap><!-- Order 实体类 -->
<resultMap id="orderMap" type="Order"><id property="id" column="id" /><result property="orderName" column="order_name" />
</resultMap><!-- 查询用户信息的 SQL -->
<select id="selectUser" resultMap="userMap">SELECT u.id, u.usernameFROM users uWHERE u.id = #{userId}
</select><!-- 查询用户订单的 SQL -->
<select id="selectOrdersByUserId" resultMap="orderMap">SELECT o.id, o.order_nameFROM orders oWHERE o.user_id = #{userId}
</select>
3.2 使用方式
User user = userMapper.selectUser(1);
System.out.println(user.getUsername());for (Order order : user.getOrders()) {System.out.println(order.getOrderName());
}

以上3种方式都能够实现一对多的关联查询,选择哪种方式取决于个人或项目的偏好。在实际应用中,根据业务需求和性能考虑,选择合适的方式。

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

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

相关文章

poi-tl模板引擎根据树形结构输出word文档(文档模板)

最近在做一个需求&#xff0c;就是根据当前的树形结构&#xff0c;输出到word文档中。下面展示一下小demo 目录 1、输入&#xff1a; 2、输出&#xff1a;文档.docx 3、代码展示 4、测试结果 4.1、模板文档内容 4.2、输出文档 5、总结 1、输入&#xff1a; root---树节…

Unity New Input System 及其系统结构和源码浅析【Unity学习笔记·第十二】

转载请注明出处&#xff1a;&#x1f517;https://blog.csdn.net/weixin_44013533/article/details/132534422 作者&#xff1a;CSDN|Ringleader| 主要参考&#xff1a; 官方文档&#xff1a;Unity官方Input System手册与API官方测试用例&#xff1a;Unity-Technologies/InputS…

Aria2 WebUI控制台 任意文件读取漏洞复现(CVE-2023-39141)

0x01 产品简介 Aria2 WebUI控制台是用于下载文件的实用程序。它支持 HTTP(S)/FTP/SFTP/BitTorrent 和 Metalink 协议。aria2可以从多个来源/协议下载文件,并尝试利用您的最大下载带宽。它支持同时从HTTP(S)/FTP/SFTP和BitTorrent下载文件,而从HTTP(S)/FTP/SFTP下载的数据上…

算法之【前缀和】讲解

前言&#xff1a; 我们首先要明白何前缀和&#xff1f; 前缀和就是快速求出数组中某一个连续区间的和。算法的时间复杂度会将一个等级&#xff01; 本文章主要讲解前缀和模板&#xff0c;分别为一维前缀和和二维前缀和。 一维前缀和&#xff1a; 第一步&#xff1a;预处理…

Vue+ElementUI渲染select下拉框

User.java /*实现getter和setter方法注解*/ Data public class User {private Integer id;private String name; } UserMapper.java Mapper public interface CommonUserMapper {/**查询所有*/List<CommonUser> selectAllCommonUser(); } UserMapper.xml <?xml …

makefile 编译动态链接库使用(.so库文件)

makefile 编译动态链接库使用&#xff08;.so库文件&#xff09; 动态链接库:不会把代码编译到二进制文件中&#xff0c;而是在运行时才去加载&#xff0c; 好处是程序可以和库文件分离&#xff0c;可以分别发版&#xff0c;然后库文件可以被多处共享 动态链接库 动态&#…

支付宝:多线程事务怎么回滚?说用 @Transactional 可以回去等通知了!

1&#xff0c;最近有一个大数据量插入的操作入库的业务场景&#xff0c;需要先做一些其他修改操作&#xff0c;然后在执行插入操作&#xff0c;由于插入数据可能会很多&#xff0c;用到多线程去拆分数据并行处理来提高响应时间&#xff0c;如果有一个线程执行失败&#xff0c;则…

2011-2022年全国各地级市互联网普及率/互联网宽带接入用户数数据

2011-2022年全国各地级市互联网宽带接入用户数/互联网普及率数据 1、时间&#xff1a;2011-2022年 2、范围&#xff1a;包括295个地级市 3、指标&#xff1a;行政区划代码、年份、地区、互联网宽带接入用户_千户、常住人口数_千人、户籍人口数_千人、每百人互联网宽带用户_常…

续签KES证书

MiniO KES&#xff08;密钥加密服务&#xff09;是 MinIO 开发的一项服务&#xff0c;旨在弥合在 Kubernetes 中运行的应用程序与集中式密钥管理服务 &#xff08;KMS&#xff09; 之间的差距。中央 KMS 服务器包含所有状态信息&#xff0c;而 KES 在需要执行与获取新密钥或更新…

docker运行redis,jdk,nginx

Redis 1.查询redis [rootlocalhost ~]# docker search redis NAME DESCRIPTION STARS OFFICIAL redis Redis is an open source key-value store that… 12620 …

网络安全全栈培训笔记(WEB攻防-51-WEB攻防-通用漏洞验证码识别复用调用找回密码重定向状态值)

第51天 WEB攻防-通用漏洞&验证码识别&复用&调用&找回密码重定向&状态值 知识点&#xff1a; 1、找回密码逻辑机制-回显&验证码&指向 2、验证码验证安全机制-爆破&复用&识别 3、找回密码客户端回显&Response状态值&修改重定向 4、…

革新区块链:代理合约与智能合约升级的未来

作者 张群&#xff08;赛联区块链教育首席讲师&#xff0c;工信部赛迪特聘资深专家&#xff0c;CSDN认证业界专家&#xff0c;微软认证专家&#xff0c;多家企业区块链产品顾问&#xff09;关注张群&#xff0c;为您提供一站式区块链技术和方案咨询。 代理合约&#xff08;Prox…