mybatis高级查询:一对多配置,一次性查出主表和子表中的数据

本文章已经生成可运行项目,

一、MyBatis高级查询:一对多

MyBatis是一款强大的持久层框架,提供了多种方式来处理关联查询,其中包括一对一和一对多的情况。在本文中,我们将深入探讨一对多关联查询的实现方式。

在MyBatis中配置一对多关系通常涉及到associationcollection元素的使用。一对多关系指的是一个实体类(例如,一个部门)与多个实体类(例如,该部门的多个员工)之间的关系。

一对多查询,也称为“主从查询”或“嵌套查询”,是指在一个数据库查询中,一个主表记录可以关联多个从表记录的情况。在 MyBatis 中,一对多查询通常通过 resultMap 和 association/collection 标签来实现。

resultMap:resultMap 是 MyBatis 中用于定义如何从数据库结果集映射到 Java 对象的一个高级特性。它允许你完全控制如何将结果集中的列映射到对象的属性上。
association:用于处理一对一的关联关系。
collection:用于处理一对多的关联关系。

对多查询的场景

一对多查询在数据库设计中非常常见,例如:

  • 一个订单(Order)包含多个订单项(OrderItem)。
  • 一个用户(User)拥有多个地址(Address)。
  • 一个部门(Department)有多个员工(Employee)。

这些场景都可以通过一对多查询来实现。

下面是如何在MyBatis的映射文件中配置一对多关系的详细步骤:

二、使用实战:

1. 定义结果映射(Result Map)

首先,你需要为涉及的每一个实体类定义一个结果映射(Result Map)。这对于associationcollection元素来说非常重要。

示例:

假设有两个类,DepartmentEmployee,其中Department包含多个Employee

Department.java 

public class Department {
    private Integer id;
    private String name;
    private List<Employee> employeeList;
    // getters and setters
}

 Employee.java

public class Employee {
    private Integer id;
    private String name;
    private Integer departmentId;
    // getters and setters
}

2. 配置Result Map

在MyBatis的映射文件中,为DepartmentEmployee配置结果映射。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xx.mapper.xxMapper">
	<sql id="department_column_list">
		d.id as id,
		d.name as name
	</sql>

	<sql id="employee_column_list">
		e.id as id,
		e.name as name,
		e.department_id as departmentId
	</sql>

	<!-- 1. 查询主表数据 -->
	<select id="selectDepartment" parameterType="com.xx.dto.DepartmentDTO" resultMap="employeeResultMap">
		select
		<include refid="Base_Column_List" />
		FROM department d
		where d.delete_flag = '0'
		<if test="id != null and  id != '' ">
			and d.id = #{id}
		</if>
		ORDER BY d.id desc
	</select>
	
	<!-- 1. 查询主表并关联外键表 -->
	<resultMap id="employeeResultMap" type="com.xx.domain.vo.DepartmentVO">
		<!-- 关联外键表 List<Employee> employees-->
		<collection property="employeeList" ofType="com.xx.domain.Employee" column="{fkDepartmentId=id}" select="selectEmployeeList"/>
	</resultMap>

	<select id="selectEmployeeList" resultType="com.xx.domain.Employee">
		select
		<include refid="employee_column_list" />
		from employee e where e.fk_department_id = #{fkDepartmentId}
		ORDER BY e.id desc
	</select>
</mapper>

 配置关联对象解释,其中:

property属性值为当前Department对象的关联对象名;

ofType属性值为关联对象属性所属的完全限定类名或别名;

select属性值为所请求的select映射的ID,该select使用子查询获取其所关联的属性对象;

column属性值为关联主键ID

在上面的配置中,我们定义了一个名为 employeeResultMap 的 resultMap,用于将数据库结果集映射到 Department 对象。其中,collection 标签用于处理一对多的关联关系,它指定了 employee 属性的映射规则。column 属性指定了用于嵌套查询的列,select 属性指定了嵌套查询的 SQL 语句(即 selectEmployeeList)。

3.使用 : Mapper 接口

Page<DepartmentVO> selectDepartmentPage(DepartmentDTO  dto);

4.接口效果: 

一次性查出:

{
	"status": 200,
	"message": "查询成功",
	"data": [{
		"id": 394238111271489537,
		"name": "部门一",
		"employeeList": [{
			"id": 394238111271489538,
			"name": "员工一",
			"departmentId": 394238111271489537
		},
		{
			"id": 394238111271489538,
			"name": "员工二",
			"departmentId": 394238111271489537
		},
		{
			"id": 394238111271489538,
			"name": "员工三",
			"departmentId": 394238111271489537
		}]

	}]
}

三、注意事项

性能优化:虽然一对多查询在功能上非常强大,但在性能上可能会面临一些挑战。特别是当关联的数据量很大时,可能会导致查询速度变慢。因此,在实际应用中,我们需要根据具体场景进行性能优化,例如使用分页查询、延迟加载等技术。
事务管理:在进行一对多查询时,如果涉及到多个表的更新操作,我们需要确保这些操作在同一个事务中完成,以保证数据的一致性。MyBatis 提供了事务管理的支持,我们可以在配置文件中进行配置。
缓存机制:为了提高查询效率,MyBatis 提供了缓存机制。我们可以利用 MyBatis 的一级缓存和二级缓存来减少数据库的访问次数。同时,我们也可以使用第三方缓存框架(如 Redis)来进一步优化性能。

https://blog.youkuaiyun.com/m0_70066267/article/details/142901590

https://blog.youkuaiyun.com/weixin_43819566/article/details/116268829 

https://blog.youkuaiyun.com/2301_77072336/article/details/135159401 

本文章已经生成可运行项目
在使用Mybatis Plus进行主表查明细的操作时,可以使用Mybatis Plus提供的关联查询功能来实现。首先,需要在主表的实体类中定义与明细表实体类的关联关系。可以通过注解或者XML方式定义关联关系。接下来,在查询主表数据时,使用关联查询功能同时查询明细表的数据。 示例代码如下所示: ```java // 主表实体类 public class MainTable { // 主表字段 // ... // 明细表关联对象 @TableField(exist = false) private DetailTable detailTable; // gettersetter方法 // ... } // 明细表实体类 public class DetailTable { // 明细表字段 // ... } // Mybatis Plus查询主表并关联查询明细表 public List<MainTable> queryMainTableWithDetail() { QueryWrapper<MainTable> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("条件字段", "条件值"); List<MainTable> mainTableList = mainTableMapper.selectList(queryWrapper); // 关联查询明细表 if (mainTableList != null && !mainTableList.isEmpty()) { List<Long> detailTableIds = mainTableList.stream() .map(MainTable::getDetailTableId) .collect(Collectors.toList()); QueryWrapper<DetailTable> detailQueryWrapper = new QueryWrapper<>(); detailQueryWrapper.in("id", detailTableIds); List<DetailTable> detailTableList = detailTableMapper.selectList(detailQueryWrapper); // 将明细表数据主表数据进行关联 Map<Long, DetailTable> detailTableMap = detailTableList.stream() .collect(Collectors.toMap(DetailTable::getId, Function.identity())); for (MainTable mainTable : mainTableList) { DetailTable detailTable = detailTableMap.get(mainTable.getDetailTableId()); mainTable.setDetailTable(detailTable); } } return mainTableList; } ``` 以上代码通过使用Mybatis Plus提供的查询包装器(QueryWrapper)来构造查询条件,然后使用关联查询功能查询主表数据,并通过关联表的ID字段进行关联查询明细表数据。最后,将查询到的明细表数据主表数据进行关联,返回关联后的结果。 请注意,具体的表名、字段名以及Mapper接口的命名需要根据实际情况进行修改。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [如何使用自定义Mybatis-TypeHandler直接将查询到的JSON数据封装到指定对象,达到可复用?](https://blog.youkuaiyun.com/qq_38338409/article/details/124227723)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [探索Mybatis中Mapper默认返回值](https://blog.youkuaiyun.com/zhuqiuhui/article/details/87899146)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alex_81D

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值