• MyBatis标签之Select resultType和resultMap


    MyBatis常用动态标签大全见上述URL,它们大概分为如下四类:

    标签作用使用场景
    foreach循环语句批量添加或者批量查询
    if条件判断语句单条件分支判断
    choose、when、otherwise类似 Java 中的 switch、case、default 语句多条件分支判断
    trim、where、set辅助标签用于处理一些条件查询

    在MyBatis中有一个ResultMap标签,它是为了映射select标签查询出来的结果集,其主要作用是将实体类中的字段与数据库表中的字段进行关联映射。

    前言

    Mybatis 中 select 标签有两个属性 resultType 和 resultMap,用于在mapper.xml文件中配置返回结果类型,工作中经常使用到它们。那么在日常开发中,应该如何正确的选择呢?下面我们对这两个属性分别进行讲解和演示。

    结果类型resultType

    resultType直译就是结果的类型,可以设置为期望从select 语句中返回结果的类的 全限定名 或 别名 。resultType使用场景如下:

    如果查询结果只是返回一个值,比如返回String、map或int,那么可以使用resultType指定简单类型作为输出结果。

    我们先了解一个resultType的简单映射语句示例,它没有显式地指定 resultMap 。比如:

    
        id, username, hashedPassword
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    上述语句只是简单地将所有的列映射到 HashMap 的键上,这由 resultType 属性指定。此处对查询字段用了一个 sql 标签进行封装,该sql 片段可复用。

    还有一种情况就是如果数据库表的字段名和实体bean对象的属性名一样。 虽然在大部分情况下都够用,但是 HashMap 并不是一个很好的领域模型;你的程序更可能会使用 JavaBean 或 POJO(普通老式 Java 对象)作为领域模型,MyBatis 对两者都提供了支持。看看下面这个 JavaBean:

    package com.someapp.model;
    public class User {
      private int id;
      private String username;
      private String hashedPassword;
    
     // omit getter,setter and toString
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    基于 JavaBean 的规范,上面这个类有 3 个属性:id,username 和 hashedPassword,它们会对应到 select 语句中的列名。这样的一个 JavaBean 可以被映射到 ResultSet ,就像映射到 HashMap 一样简单。

    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    类型别名是你的好帮手,关于如何设置类型别名,请移步《 Spring Boot MyBatis使用type-aliases-package自定义类别名 》。使用别名后就可以不用输入类的全限定名了。譬如:

    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在此情况下,MyBatis 会在幕后自动创建一个 resultMap ,再根据属性名来映射列到 JavaBean 的属性上。如果列名和属性名不能匹配上,可以在 SELECT 语句中设置列别名(这是一个基本的 SQL 特性)来完成匹配。例如:

    
        user_id             as "id",
        user_name           as "userName",
        hashed_password     as "hashedPassword"
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。

    结果映射resultMap

    resultMap 直译就是结果映射,该元素是 MyBatis 中最重要最强大的元素。与 resultType 相比,resultMap就要强大许多,它不仅能够用于简单查询,还能用于级联查询以及设置缓存,功能可谓是十分的强大。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的数千行代码。 ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了 。温馨提示:resultType 和 resultMap 之间只能同时使用一个。

    resultMap标签属性

    resultMap 标签的属性值包括两个:

    id 属性:唯一标识,此 id 值用于 select 标签 resultMap 属性的引用。

    type 属性:表示该 resultMap 的映射结果类型,可以为类的全限定名或者别名。

    resultMap子标签包括如下几个 :

    子标签功能备注
    id指定查询列中的唯一标识,如果有多个列组成唯一标识,配置多个id可以不用
    result用于标识一些简单属性,包括column和property两个属性常用
    association在主表的pojo中嵌套另一个表的pojo不推荐使用
    collection把查询到的多条记录映射到集合对象不推荐使用

    result标签的属性包括两个:

    1. column :数据库字段名或别名。
    2. property :实体类中的属性,和column属性一一对应。
    resultMap使用示例

    下面使用一个简单的例子,来介绍 resultMap 的使用方法。虽然上一节中的例子不用显式配置 resultMap ,但为了讲解,我们来看看如果显式使用外部的 resultMap 会怎样;这也是解决列名和bean名不匹配的另外一种方式。定义一个resultMap:

    
      
      
      
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    然后在引用它的语句中设置 resultMap 属性就行了(注意我们去掉了 resultType 属性)。比如:

    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    resultType和resultMap的区别

    下面了解一下MyBatis中数据转换机制:在进行查询映射的时候,其实查询出来的每一个属性都是放在一个对应的Map里面,其中键是属性名,值则是其对应的值。当提供的返回类型属性是resultType的时候,MyBatis会将Map里面的键值对取出赋给resultType所指定的对象对应的属性。所以,其实MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候,MyBatis自动的把对应的值赋给resultType所指定对象的属性,而当提供的返回类型是resultMap的时候,因为Map不能很好表示领域模型,我们就需要自己把它转化为对应的对象,这常常在复杂查询中很有作用。

    言归正传,resultType和resultMap到底有什么区别呢?

    resultType不需要配置,但是resultMap要配置一下。resultType是直接指定返回类型的,而使用resultMap时,需要在外部ResultMap标签中,设置数据库表的字段名和实体bean对象类的属性的一一对应关系。设置后,就算数据库的字段名和实体类的属性名不一样也没有关系,mybatis依然会给映射出来,所以resultMap要更强大一些。

    就像上面说的那样,如果查询出来数据库字段名(包括字段别名)和要封装的实体bean对象属性值不相同时,只能使用resultMap来返回结果。

    还有一个区别是 resultMap可以用在复杂联合查询上,而resultType不可以 。关于这一点,大家可以去Mybatis官网了解一下,这里点到为止。

    结束语

    至此,大家已经了解了resultType和resultMap的基本用法,在日常业务开发中已经可以游刃有余了。如果想更上一层楼,掌握更多关于resultMap的高级用法,请移步 Mybatis官网 。

    当你遇到这个话题的时候,你通常怎么理解呢?你碰到过特别精彩、让人印象深刻的回答吗?欢迎大家积极留言交流

  • 相关阅读:
    (2022牛客多校五)G-KFC Crazy Thursday(二分+哈希)
    喜马拉雅 Redis 与 Pika 缓存使用军规
    Python是否被高估了?
    ISO质量认证范围和审核范围的简要解说
    Spring整合Junit(单元测试)
    【大数据 minio】10分钟了解大数据存储的方案minio
    一口气说出 Synchronized 同步方法的八种使用场景
    功率放大器的设计要点
    华为云云耀云服务器L实例使用教学:快速安装mysql
    【python】JSON标准库文件介绍及python中json模块使用
  • 原文地址:https://blog.csdn.net/Huangjiazhen711/article/details/126929037