【Mybatis用法】Mybatis 高级结果映射,ResultMap Association,mybatis的一对多,多对一,以及多对多的配置和使用

简介: 【Mybatis用法】Mybatis 高级结果映射,ResultMap Association,mybatis的一对多,多对一,以及多对多的配置和使用

一、背景描述

需求:查询任务逾期记录时,把任务相关信息查询出来;

表设计:任务相关信息是一张表(uoa_assignment),任务逾期记录是一张表(uoa_assignment_overdue_log);外键是任务主键(id);

JavaBean:class Assignment, class AssignmentOverdueLog; class AssignmentOverdueLog中包含class Assignment对象。

目的:在查询任务逾期记录时,两张表关联查询出来之后,想要把Assignment的结果集映射到AssignmentOverdueLog中。

两个JavaBean对象如下:AssignmentOverdueLog对象中包含一个Assignment对象。

在查询任务逾期记录时,两张表关联查询出来之后,想要把Assignment的结果集映射到AssignmentOverdueLog中。

二、解决方案

mapper.xml中正确的写法

方法1

写两个<resultMap></resultMap>,通过<association>标签关联起来,然后在查询的sql语句结果集映射中填写外层的<resultMap>的属性id。

在上面的例子中,您会看到AssignmentOverdueLog联合一个“assignmentResultMap”结果映射来加载Assignment实例。

重点提示:id元素在嵌套结果映射中扮演了非常重要的角色,您应该总是指定一个或多个属性来唯一标识这个结果集。事实上,如果您没有那样做,MyBatis也会工作,但是会导致严重性能开销。选择尽量少的属性来唯一标识结果,而使用主键是最明显的选择(即使是复合主键)。

上面的例子使用一个扩展的resultMap 元素来联合映射。这可使Assignment结果映射可重复使用

然后,如果您不需要重用它,您可以直接嵌套这个联合结果映射。这就是另外一种写法了。

方法2

方法3

上面的例子,首先执行<select id=“queryListByLastMonth”>,执行结果存放到<resultMap id=“assignmentOverdueLogMap”>结果映射中。“assignmentOverdueLogMap”是一个AssignmentOverdueLog类型,从<select id=“queryListByLastMonth”>查出的数据都会自动赋值给”assignmentOverdueLogMap”的与列名匹配的属性,这时assignment_id,responsibleUser,responsibleName等就被赋值了。同时“assignmentOverdueLogMap”还有一个关联属性"assignment",执行嵌套查询select=”getAssignment”后,Assignment对象的属性id,type,transactType,title,description等也被赋于数据库中匹配的值。

我们使用两个select语句:一个用来加载AssignmentOverdueLog,另一个用来加载Assignment。AssignmentOverdueLog的resultMap 描述了使用“getAssignment”语句来加载Assignment的属性。

如果列名和属性名称相匹配的话,所有匹配的属性都会自动加载。

虽然这个方法简单,但是对于大数据集或列表查询,就非常不友好了。此问题被称为“N+1 选择问题”(N+1 Selects Problem)。概括地说,N+1选择问题是这样产生的:

1、您执行单条SQL语句去获取一个列表的记录( “+1”)。

2、对列表中的每一条记录,再执行一个联合select 语句来加载每条记录更加详细的信息(“N”)。

这个问题会导致成千上万的SQL语句的执行,因此并非总是可取的。

上面的例子,MyBatis可以使用延迟加载这些查询,因此这些查询立马可节省开销。然而,如果您加载一个列表后立即迭代访问嵌套的数据,这将会调用所有的延迟加载,因此性能会变得非常糟糕。

鉴于此,这有另外一种方式。联合嵌套结果集(Nested Results for Association),也就是上面的方法1和方法2两种方式。

会用到ResultMap联合嵌套结果集(Nested Results for Association)

ResultMap 一个可以映射联合嵌套结果集到一个适合的对象视图上的ResultMap 。这是一个替代的方式去调用另一个select 语句。它允许您去联合多个表到一个结果集里。这样的结果集可能包括冗余的、重复的需要分解和正确映射到一个嵌套对象视图的数据组。简言之,MyBatis 让您把结果映射‘链接’到一起,用来处理嵌套结果。也就是上面的方法1和方法2两种方式。

 

在上面的例子中您已经看到如果处理“一对一”(“has one”)类型的联合查询。但是对于“一对多”(“has many”)的情况如果处理呢?这个问题在下一节讨论:(待补充........)。

 

 

 

拓展:

<association property="assignment" javaType="com.iot.uoa.assignment.entity.Assignment">
  <result property="id" column="id"/>
  <result property="type" column="task_type"/>
  <result property="title" column="title"/>
  <result property="responsibleUser" column="responsible_user"/>
  <result property="responsibleName" column="responsible_name"/>
  <result property="transactType" column="transact_type"/>
  <result property="description" column="description"/>
  <result property="taskLevel" column="task_level"/>
</association>

Association元素处理“has-one”(一对一)这种类型关系。比如在我们的例子中,一个AssignmentOverdueLog有一个Assignment。联合映射与其它的结果集映射工作方式差不多,指定property、column、javaType(通常MyBatis会自动识别)、jdbcType(如果需要)、typeHandler。

不同的地方是您需要告诉MyBatis 如何加载一个联合查询。MyBatis使用两种方式来加载:

Select:通过执行另一个返回预期复杂类型的映射SQL语句(即引用外部定义好的SQL语句块)。

Results:通过嵌套结果映射(nested result mappings)来处理联接结果集(joined results)的重复子集。

首先,让我们检查一下元素属性。正如您看到的,它不同于普通只有selectresultMap属性的结果映射。

属性 描述
property 映射数据库列的字段或属性。如果JavaBean 的属性与给定的名称匹配,就会使用匹配的名字。否则,MyBatis 将搜索给定名称的字段。两种情况下您都可以使用逗点的属性形式。比如,您可以映射到”username”,也可以映射到更复杂点的”address.street.number”。
column

数据库的列名或者列标签别名。与传递给resultSet.getString(columnName)的参数名称相同。

注意: 在处理组合键时,您可以使用column= “{prop1=col1,prop2=col2}”这样的语法,设置多个列名传入到嵌套查询语句。这就会把prop1和prop2设置到目标嵌套选择语句的参数对象中。

javaType 完整java类名或别名(参考上面的内置别名列表)。如果映射到一个JavaBean,那MyBatis 通常会自行检测到。然而,如果映射到一个HashMap,那您应该明确指定javaType 来确保所需行为。
jdbcType 支持的JDBC类型列表中列出的JDBC类型。这个属性只在insert,update 或delete 的时候针对允许空的列有用。JDBC 需要这项,但MyBatis 不需要。如果您直接编写JDBC代码,在允许为空值的情况下需要指定这个类型。
typeHandler 我们已经在文档中讨论过默认类型处理器。使用这个属性可以重写默认类型处理器。它的值可以是一个TypeHandler实现的完整类名,也可以是一个类型别名。

显示详细信息

联合嵌套选择(Nested Select for Association)

select 通过这个属性,通过ID引用另一个加载复杂类型的映射语句。从指定列属性中返回的值,将作为参数设置给目标select 语句。表格下方将有一个例子。注意:在处理组合键时,您可以使用column=”{prop1=col1,prop2=col2}”这样的语法,设置多个列名传入到嵌套语句。这就会把prop1和prop2设置到目标嵌套语句的参数对象中。

 

 

 

完结!

 

相关文章
|
SQL XML Java
七、MyBatis自定义映射resultMap
七、MyBatis自定义映射resultMap
413 6
|
XML Java 数据库连接
Mybatis一对一,一对多关联查询
## MyBatis一对一、一对多关联查询详解 MyBatis是一款优秀的持久层框架,提供了灵活的SQL映射功能,支持复杂的数据库操作。本文将详细介绍MyBatis中一对一和一对多关联查询的实现。 ### 一对一关联查询 一对一关联关系指的是一个表中的一条记录与另一个表中的一条记录相关联。例如,一个用户有一个地址信息。 #### 数据库表设计 假设有两个表:`user`和 `address`。 ``` CREATE TABLE user ( id INT PRIMARY KEY, name VARCHAR(50) ); CREATE TABLE address
555 18
mybatis复习02,简单的增删改查,@Param注解多个参数,resultType与resultMap的区别,#{}预编译参数
文章介绍了MyBatis的简单增删改查操作,包括创建数据表、实体类、配置文件、Mapper接口及其XML文件,并解释了`#{}`预编译参数和`@Param`注解的使用。同时,还涵盖了resultType与resultMap的区别,并提供了完整的代码实例和测试用例。
mybatis复习02,简单的增删改查,@Param注解多个参数,resultType与resultMap的区别,#{}预编译参数
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
文章介绍了MyBatis中高级查询的一对多和多对一映射处理,包括创建数据库表、抽象对应的实体类、使用resultMap中的association和collection标签进行映射处理,以及如何实现级联查询和分步查询。此外,还补充了延迟加载的设置和用法。
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
|
SQL XML Java
Mybatis中一对一和一对多的处理
这篇文章讲解了在Mybatis中如何处理一对一和一对多的关系映射,包括使用association和collection标签的具体方法。
494 1
|
Java 数据库连接 mybatis
后端框架的学习----mybatis框架(9、多对一处理和一对多处理)
这篇文章介绍了在MyBatis框架中如何处理多对一和一对多的关联查询,通过定义`<resultMap>`和使用`<association>`与`<collection>`元素来实现对象间的关联映射。
|
11月前
|
Java 数据库连接 数据库
Spring boot 使用mybatis generator 自动生成代码插件
本文介绍了在Spring Boot项目中使用MyBatis Generator插件自动生成代码的详细步骤。首先创建一个新的Spring Boot项目,接着引入MyBatis Generator插件并配置`pom.xml`文件。然后删除默认的`application.properties`文件,创建`application.yml`进行相关配置,如设置Mapper路径和实体类包名。重点在于配置`generatorConfig.xml`文件,包括数据库驱动、连接信息、生成模型、映射文件及DAO的包名和位置。最后通过IDE配置运行插件生成代码,并在主类添加`@MapperScan`注解完成整合
1588 1
Spring boot 使用mybatis generator 自动生成代码插件
|
XML Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——基于注解的整合
本文介绍了Spring Boot集成MyBatis的两种方式:基于XML和注解的形式。重点讲解了注解方式,包括@Select、@Insert、@Update、@Delete等常用注解的使用方法,以及多参数时@Param注解的应用。同时,针对字段映射不一致的问题,提供了@Results和@ResultMap的解决方案。文章还提到实际项目中常结合XML与注解的优点,灵活使用两者以提高开发效率,并附带课程源码供下载学习。
1078 0
|
前端开发 Java 数据库连接
Java后端开发-使用springboot进行Mybatis连接数据库步骤
本文介绍了使用Java和IDEA进行数据库操作的详细步骤,涵盖从数据库准备到测试类编写及运行的全过程。主要内容包括: 1. **数据库准备**:创建数据库和表。 2. **查询数据库**:验证数据库是否可用。 3. **IDEA代码配置**:构建实体类并配置数据库连接。 4. **测试类编写**:编写并运行测试类以确保一切正常。
766 2
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
791 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。