MyBatis教程[5]----resultMap高级结果映射、自动映射


在实际应用中,我们常常会遇到数据库中的字段和Java实体中的属性名不一致的情况,或在多表查询时需要将多个表的数据与实体属性关联起来的情况,此时就需要使用resultMap进行结果映射了。

在这里引用一下Mybatis官网对resultMap的介绍:

resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份resultMap 能够代替实现同等功能的数千行代码。ResultMap的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

既然官网都说它是最重要最强大的元素,那就让我们来看看它重要在哪里,强大在哪里吧!

1.回顾resultType

1.1 使用回顾

在此之前,先说一说我们前面几篇博客用到的一个关键字resultType

前面我们写过这样的查询语句:

<select id="selectById" resultType="com.yky.springboot.entities.User">
   SELECT * FROM `user` WHERE id = #{id}
</select>

对应的实体类是这样的:

package com.yky.springboot.entities;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable {
   
    private Long id;
    private String name;
    private String phone;
    private Date birthday;
	
	Getter、Setter方法....
	
    toString方法...
}

数据库中的字段是这样的:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(100) DEFAULT NULL COMMENT '姓名',
  `phone` varchar(20) DEFAULT NULL COMMENT '手机号',
  `birthday` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '生日',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

可以看到,数据表中的字段名和Java实体类中的字段名完全一致。此时我们便可以直接用resultType来指定将SQL执行结果映射到com.yky.springboot.entities.User类。

1.2 简化全类名

当然了,重复的写完整的类名看起来并不是很优雅,此时我们可以使用类型别名来解决,Mybatis为我们提供了typeAlias关键字,typeAlias需要写在Mybatis的全局配置文件mybatis-config.xml中。在resources下创建mybatis-config.xml文件,并写入以下代码:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    
    <typeAliases>
        <typeAlias type="com.yky.springboot.entities.User" alias="User"></typeAlias>
    </typeAliases>

</configuration>

还需要在yml文件中指定一下Mybatis全局配置文件所在路径:

mybatis:
  #配置mybatis映射文件路径
  mapper-locations: classpath:mapper/*.xml
  #配置mybatis全局配置文件所在路径
  config-location: classpath:mybatis-config.xml

此时同样的SQL语句可以这样写:

<select id="selectById" resultType="User">
   SELECT * FROM `user` WHERE id = #{id}
</select>

1.3 局限性

1. 数据库字段需要与实体类字段完全一致

这一点不用多说,毕竟字段不一样的话Mybatis是不知道怎么匹配的。

2. 对多表关联不友好甚至根本满足不了多表关联需求(一对一、一对多、多对多)

比如有一个员工类:Employee
有一个部门类:Department
部门类中有一个List<Employee> employees属性,包含部门所有员工,在这里部门与员工之间属于一对多的关系。
有以下需求:
[1] 只通过一条多表查询语句,直接查询到部门信息,以及当前部门的所有员工
[2] 将上述SQL语句查询到的信息封装到Department类中(employees保存所有员工列表)

显然这样做使用resultType是满足不了的。

鉴于resultType有种种限制,resultMap便应运而生了。

2.resultMap简单使用

resultMap最简单的应用场景是:解决数据库字段与实体属性名不一致的问题。

接下来直接上代码

有员工类:

public class Employee implements Serializable {
   
    /**
     * 主键id
     */
    private Long id;

    /**
     * 姓名
     */
    private String name;

    /**
     * 工号
     */
    private String number;

    /**
     * 部门编号
     */
    private Long departmentId;

    /**
     * 薪资
     */
    private Double salary;

	Getter(),Setter().....
	toString()....
}

有数据表:

CREATE TABLE `employee` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `employee_name` varchar(255) NOT NULL,
  `number` varchar(255) NOT NULL,
  `department_id` int(11) NOT NULL,
  `salary` decimal(10,2) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

很显然,数据表中的列名与实体类中的字段名并不一致,这时就需要用到resultMap来指定数据表中的字段与实体属性字段的一一对应关系了。
Mapper接口代码:

@Mapper
public interface EmployeeMapper {
   
    List<Employee> selectAll();
}

写在EmployeeMapper.xml中的resultMap代码:

    <resultMap id="empMap" type="com.yky.springboot.entities.Employee">
        <!--主键需要使用id标签单独写,可以提高性能-->
        <id column="id" property="id"/>

        <!--普通字段直接使用result标签-->
        <result column="employee_name" property="name"/>
        <result column="number" property="number"/>
        <result column="department_id" property="departmentId"/>
        <result column="salary" property="salary"/>
    </resultMap>

写在EmployeeMapper.xml中的SQL查询语句代码:

    <select id="selectAll" resultMap="empMap">
        SELECT * FROM employee
    </select>

上面我所举的例子是resultMap的最简单的应用了,resultMap的高级应用则体现在了多表联合映射上。

3.resultMap高级结果映射

resultMap高级结果映射,即在多表联合查询时,将结果联合映射到目标实体中。这里的目标实体通常包含其他实体对象、集合等元素。常用在一对一,一对多、多对一、多对多的关系表中。

在此之前,先列出resultMap的子元素(摘自官方教程):

  • constructor - 用于在实例化类时,注入结果到构造方法中-----当创建实体类时需要传构造参数时使用
    。idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能
    。arg - 将被注入到构造方法的一个普通结果
  • id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能-----标示主键id,可以提高性能
  • result – 注入到字段或 JavaBean 属性的普通结果-----映射普通字段
  • association – 一个复杂类型的关联;许多结果将包装成这种类型------映射实体类内部包含的其他实体类
    。嵌套结果映射 – 关联可以是 resultMap 元素,或是对其它结果映射的引用
  • collection – 一个复杂类型的集合------映射实体类中包含的集合
    。嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用
  • discriminator – 使用结果值来决定使用哪个 resultMap-----根据判断条件,有选择的映射
    。case – 基于某些值的结果映射
    • 嵌套结果映射 – case 也是一个结果映射,因此具有相同的结构和元素;或者引用其它的结果映射

在这里,我们不去讨论数据表的一对一、一对多、多对一、多对多关系。我们只试图通过下面两节展示一个稍微复杂一点的例子来演示resultMap的高级用法。

4.一条SQL语句实现多表关联映射

4.1 实体类创建

假设我们需要定义一个实体类来表示一个大学生,需要包含以下信息:

  • 姓名、性别、年龄、学号,这些属于基本信息
  • 所加入的社团,这里需要是一个包含社团对象的集合
  • 所属专业(在这里不考虑多学位情况),这里需要
  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
使用 Mybatis-Plus 进行关联查询需要添加一个名为 mybatis-plus-extension 的依赖,具体的步骤如下: 1. 在 pom.xml 文件中添加以下依赖: ``` <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus.version}</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-extension</artifactId> <version>${mybatis-plus.version}</version> </dependency> ``` 其中,mybatis-plus-boot-starter 是 Mybatis-Plus 的核心依赖,mybatis-plus-extension 是 Mybatis-Plus 的扩展依赖。 2. 在 application.yml 或 application.properties 文件中添加以下配置: ``` mybatis-plus: mapper-locations: classpath*:mapper/**/*.xml # mapper.xml文件所在路径 global-config: db-config: logic-delete-value: 1 # 逻辑删除值 logic-not-delete-value: 0 # 逻辑未删除值 configuration: map-underscore-to-camel-case: true # 开启驼峰命名转换 ``` 3. 在 mapper.xml 文件中进行关联查询的配置,例如: ``` <select id="getUserOrders" resultMap="UserResultMap"> SELECT u.id, u.name, o.order_no, o.total_price FROM user u LEFT JOIN order o ON u.id = o.user_id WHERE u.id = #{id} </select> <resultMap id="UserResultMap" type="User"> <id column="id" property="id" /> <result column="name" property="name" /> <collection property="orders" ofType="Order"> <result column="order_no" property="orderNo" /> <result column="total_price" property="totalPrice" /> </collection> </resultMap> ``` 其中,getUserOrders 是方法名,UserResultMap 是结果集映射的名称,User 是结果集映射的类型。关联查询的 SQL 语句中使用了 LEFT JOIN 进行关联,查询结果使用 resultMap 进行映射。 以上就是使用 Mybatis-Plus 进行关联查询的配置步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值