当前位置: 首页 > news >正文

Mybatis的resultMap标签介绍

说明:在Mybatis中,resultMap 标签可以用于SQL查询后的封装数据,本文用两个场景介绍 resultMap 标签的使用。

搭建环境

先搭一个Demo,pom如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.12</version>
        <relativePath/>
    </parent>


    <groupId>com.hezy</groupId>
    <artifactId>mybatis_result_demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--数据库连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>

        <dependency>
            <!--mybatis依赖-->
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <!--数据库驱动-->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

三个实体类,对应关系是:一个订单对应一个用户,一个订单对应多个订单详情

(订单)

import lombok.Data;

/**
 * 订单
 */
@Data
public class Order {

    private Long orderId;

    private Long userId;

    private String orderTitle;
}

(用户)

import lombok.Data;

/**
 * 用户
 */
@Data
public class User {

    private Long userId;

    private String username;

    private String password;
}

(订单详情)

import lombok.Data;

import java.math.BigDecimal;

/**
 * 订单详情
 */
@Data
public class OrderDetail {

    private Long orderDetailId;

    private Long orderId;

    private String productName;

    private BigDecimal productPrice;
}

数据库数据如下:

在这里插入图片描述

一对多关系

现在,我们根据订单ID查询订单,并且把对应的订单详情也关联查出来,SQL如下:

select t1.order_id,
       t1.order_title,
       t1.user_id,
       t2.order_detail_id,
       t2.product_name,
       t2.product_price
from tb_order t1
         left join tb_order_detail t2 on t1.order_id = t2.order_id
where t1.order_id = 1;

结果如下:

在这里插入图片描述

那么,我们对应的VO,应该是下面这样

import com.hezy.pojo.entity.OrderDetail;
import lombok.Data;

import java.util.List;

/**
 * 订单和订单详情VO
 */
@Data
public class OrderAndDetailVO {

    private Long orderId;

    private Long userId;

    private String orderTitle;

    /**
     * 一个订单对应多个订单详情
     */
    private List<OrderDetail> orderDetails;
}

如何把上面的SQL记录,按照 一个订单对应多个订单详情的关系 封装到VO对象中。这时,就需要使用 resultMap 标签,如下:

    <!--处理返回结果-->
    <resultMap id="selectDetailById" type="com.hezy.pojo.vo.OrderAndDetailVO">
        <result column="order_id" property="orderId" />
        <result column="user_id" property="userId" />
        <result column="order_title" property="orderTitle" />
        <collection property="orderDetails" ofType="com.hezy.pojo.entity.OrderDetail">
            <id column="order_detail_id" property="orderDetailId" />
            <result column="order_id" property="orderId" />
            <result column="product_name" property="productName" />
            <result column="product_price" property="productPrice" />
        </collection>
    </resultMap>

    <!--查询,返回结果使用对应resultMap标签处理-->
    <select id="selectOrderAndDetailById" resultMap="selectDetailById">
        select t1.order_id,
               t1.order_title,
               t1.user_id,
               t2.order_detail_id,
               t2.product_name,
               t2.product_price
        from tb_order t1
                 left join tb_order_detail t2 on t1.order_id = t2.order_id
        where t1.order_id = #{orderId}
    </select>

其中的 resultMap 可以分开下成下面这样,效果相同

	<resultMap id="selectOrderByIdResultMap" type="com.hezy.pojo.entity.Order">
	    <result column="order_id" property="orderId" />
	    <result column="order_title" property="orderTitle" />
	</resultMap>
	
	<resultMap id="selectById" type="com.hezy.pojo.vo.OrderVO" extends="selectOrderByIdResultMap">
	    <collection property="orderDetails" ofType="com.hezy.pojo.entity.OrderDetail">
	        <id column="order_detail_id" property="orderDetailId"></id>
	        <result column="order_id" property="orderId"></result>
	        <result column="product_name" property="productName"></result>
	        <result column="product_price" property="productPrice"></result>
	    </collection>
	</resultMap>

测试一下

    @Test
    public void selectTest2() {
        OrderAndDetailVO orderAndDetailVO = orderMapper.selectOrderAndDetailById(1L);
        System.out.println("orderAndDetailVO = " + orderAndDetailVO);
    }

可以看到,完全封装进来了

在这里插入图片描述

一对一关系

前面一对多关系是比较常见的,比如购物车场景、分组场景都是一对多的,一对一比较少见,这里我假设订单表里冗余了用户信息,表示某个订单只能所属于某一个用户,查询订单的同时,将该订单对应的用户信息也查出来。

对应的SQL如下:

select t1.order_id,
       t1.order_title,
       t2.user_id,
       t2.username,
       t2.password
from tb_order t1
         left join tb_user t2 on t1.user_id = t2.user_id
where t1.order_id = 1

结果如下:

在这里插入图片描述

那对应的VO如下:

import com.hezy.pojo.entity.User;
import lombok.Data;

/**
 * 订单和用户信息VO
 */
@Data
public class OrderAndUserVO {

    private Long orderId;

    private String orderTitle;

    private User user;
}

使用 resultMap 封装查询结果,如下,使用 association 标签

    <!--处理返回结果-->
    <resultMap id="selectUserById" type="com.hezy.pojo.vo.OrderAndUserVO">
        <result column="order_id" property="orderId" />
        <result column="order_title" property="orderTitle" />
        <association property="user" javaType="com.hezy.pojo.entity.User">
            <id column="user_id" property="userId" />
            <result column="username" property="username" />
            <result column="password" property="password" />
        </association>
    </resultMap>

    <select id="selectOrderAndUserById" resultMap="selectUserById">
        select t1.order_id,
               t1.order_title,
               t2.user_id,
               t2.username,
               t2.password
        from tb_order t1
                 left join tb_user t2 on t1.user_id = t2.user_id
        where t1.order_id = #{orderId}
    </select>

测试一下

    @Test
    public void selectTest3() {
        OrderAndUserVO orderAndUserVO = orderMapper.selectOrderAndUserById(2L);
        System.out.println("orderAndUserVO = " + orderAndUserVO);
    }

可以看到,也封装进来了。

在这里插入图片描述

另外

在阿里巴巴Java代码规范中,有下面这条

在这里插入图片描述

简单说,JavaBean中表示是否的属性命名,不要以“is”开头,但MySQL中表示是否关系的字段必须以“is”开头,所以查询后需要使用resultMap映射。

博主在日常工作中,遇到过这样的情况,VO对象中表示是否启用的字段名是isActivity,返回给前端的数据无故多出来了一个activity字段,就是由“isActivity"字段衍生出来的。另外遇到一些序列化错误,也是因为JavaBean中有这样的属性。

总结

本文介绍了Mybatis中resultMap标签的使用

http://www.dtcms.com/a/101415.html

相关文章:

  • Java面试黄金宝典23
  • 鸿蒙ArkTS开发:微信/系统来电通话监听功能实现
  • pycharm-qt56pyside-常用控件
  • Dubbo 框架内置的并发控制策略
  • Maven:Java项目构建与依赖管理工具
  • 解释Node.js,Node.js环境
  • 数据结构每日一题day7(顺序表)★★★★★
  • WEB安全--RCE--RCE的绕过
  • 网络深处的守门人
  • 马达加斯加企鹅字幕
  • 网站安全专栏-------DDOS常见的解决办法和防范措施
  • Vue 3 模板引用(Template Refs)详解与实战示例
  • Redis-06.Redis常用命令-列表操作命令
  • Zookeeper中的Zxid是如何设计的
  • leetcode144.二叉树展开为链表
  • Linux SCP传输文件免密配置
  • 硕士毕设-语义分割-4-通过grounding-sam生成效果很好的pesudo
  • 【图论】最短路径问题总结
  • 伴伴租赁系统-物品售卖-二手回收-物品租赁-支持微信/支付宝小程序/app/h5
  • 通过Spring Boot集成WebSocket进行消息通信
  • Java开发者指南:深入理解HotStuff新型共识算法
  • 图文档的安全管理软件有哪些?
  • pyproj 库中 Geod 类讲解
  • RK3568使用gpio子系统完成led驱动程序编写
  • f103.delay,teitou
  • docker-compose部署prometheus+grafana+node_exporter+alertmanager规则+邮件告警
  • DevOps部署平台
  • 【数论2】
  • 【ArcGIS操作】ArcGIS 进行空间聚类分析
  • 全星研发管理APQP软件系统:驱动汽车产品研发全周期,打造高效合规的质量管理引擎