resultMap 用法?工作中是怎么实现“多表联查”的?

目录

一、resultMap用法

1.1、使用场景

1.2、用法说明

1.2.1、模拟场景

1.2.2、使用

二、多表联查

2.1、分析

2.2、具体步骤

2.3、总结


一、resultMap用法


1.1、使用场景

  • 字段名称和程序中的属性名不同的情况,可使⽤ resultMap 配置映射;
  • ⼀对⼀和⼀对多关系可以使⽤ resultMap 映射并查询数据(在多表查询中,resultMap 不是企业中最常用的,后面讲多表查询的时候会讲一种最常用的方法)。

Ps拓展:

当程序中的属性名和表中的字段名不一致时的解决方案有两种:

1、使用 resultMap 标签(本篇重点讲解)。

2、使用数据库中的别名 as 重命名。

1.2、用法说明

1.2.1、模拟场景

例如,我们的表是这样定义的,如下:

但是程序中定义的熟悉如下(username字段 变成了 name属性):

这时候如果通过id来查询用户的全部数据,那么得到的 userinfo 对象的 name 属性值就为空,也就是说,当表中的字段名和属性名不一致时,查询到该属性的值就是空

1.2.2、使用

这时候可以使用 resultMap来映射不一样的字段名就可以解决上述问题,如下:

    <resultMap id="baseMap" type="com.example.demo.entity.Userinfo">
        <id column="id" property="id"></id>
        <result column="username" property="name"></result>
        <result column="password" property="password"></result>
        <result column="photo" property="photo"></result>
        <result column="createtime" property="createtime"></result>
        <result column="updatetime" property="updatetime"></result>
        <result column="state" property="state"></result>
    </resultMap>

    <select id="getUserById" resultMap="baseMap">
        select * from userinfo where id = ${id}
    </select>

解释:

 

二、多表联查


2.1、分析

也许你听到过使用 association 进行多表联查,但是对于现在的项目而言(除了银行的项目),对于多表查询最终的两个解决方案:

a)联合查询语句(left join / right join...) + XXXVO 来解决(这里的XXX 表示类名,VO 是 ViewObject 的缩写,这个类表示:是在一个实体类的基础上多加了一些属性值而新创建的一个类)。

例如:现在有一个文章表(articleinfo),和一个用户表(userinfo)如下,需要通过查询用户的 id 来查询该用户的所有文章,我们需要保留的字段为 文章表的所有信息 和 用户表的用户名,那么我们的 sql 可以这样写,如下(例如查询 id = 1):

select a.*, u.username from articleinfo a 
left join userinfo u 
on a.uid = u.id 
where u.id = 1;

b)推荐:在代码中处理联查(主要是为了解决大量数据下,多表联查带来的性能损耗).  例如有一个文章表,关联了图片表、统计表...  这些都可以直接在代码中通过一个关联字段,分别查询这几个表,最后在通过 StreamAPI流处理 + map 整合即可. 

2.2、方法一:直接copy父类属性

具体的,我们按照如下步骤进行联合查询:

a)创建一个  XXXVO  类,它的基础实体类为 文章表 ,通过上面的 sql 查询可以知道,还需要增加 用户表的用户名属性,如下代码:

@Data
public class ArticleinfoVO extends Articleinfo implements Serializable {

    private final long serializable = 1L;//用来保证兼容序列化和反序列化版本;


    //新增的属性(用户表的用户名)
    private String username;

    //以前创建的基础表具有的属性
    private int id;
    private String title;
    private String content;
    private String createtime;
    private String updatetime;
    private int uid;
    private int rcount;
    private int state;

}

Ps:

1.继承 Serializable 接口是为了防止序列化和反序列化会出问题(建议实体类都写上!防止某些特定场景报错(例如使用Redis缓存就一定会报错));

2.private final long serializable = 1L; 用来保证兼容序列化和反序列化版本,当有新版本出现时,直接修改值即可。

b)设计接口,传入 id 即可,如下代码:

import com.example.demo.entity.vo.ArticleinfoVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface ArticleMapper {

    ArticleinfoVO getAllVOById(@Param("id") Integer id);

}

Ps:注意返回类型是 XXXVO 类

c)在 XXXMapper.xml 文件中,实现对应 sql 即可,如下代码:

    <select id="getAllVOById" resultType="com.example.demo.entity.vo.ArticleinfoVO">
        select a.*, u.username from articleinfo a
        left join userinfo u on a.uid = u.id
        where a.id = #{id}
    </select>

2.3、方法二:继承父类属性

和方法一的步骤一样,唯一需要我们进行修改的就是 XXXVO 类这里我们使用一个继承的方式,如下:

import com.example.demo.entity.Articleinfo;
import lombok.Data;

@Data
public class ArticleinfoVO extends Articleinfo implements Serializable {

    private final long serializable = 1L;//用来保证兼容序列化和反序列化版本;


    //新增的属性(用户表的用户名)
    private String username;

    //这里由于 lombok 的原因( lombok 的 toString 方法不会描述父类的属性),
    @Override
    public String toString() {
        return "ArticleinfoVO{" +
                "username='" + username + '\'' +
                "} " + super.toString();
    }
}

值得注意的是:我们需要重写 toString 方法,因为 lombok 的 toString 方法不会描述父类的属性!

2.4、总结

这样就可以实现一个更简单的联合查询啦~ 这种方式具有更高的灵活性,如果联合查询结果需要更多的属性时,那么只需要重新创建一个类,赋值旧的实体类,增加新的属性值即可~

  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
ResultMapMyBatis 中用于映射查询结果的一个标签,它可以将查询结果集中的列映射到 Java 对象的属性上,从而方便我们进行数据操作。 下面是 ResultMap 的使用方法: 1. 在 MyBatis 的配置文件中定义 ResultMap ```xml <resultMap id="userMap" type="com.example.User"> <id property="id" column="user_id"/> <result property="username" column="user_name"/> <result property="password" column="user_password"/> <result property="email" column="user_email"/> </resultMap> ``` 上面的代码中,我们定义了一个名为 userMapResultMap,它将查询结果集中的列 user_id、user_name、user_password、user_email 分别映射到 User 对象中的 id、username、password、email 属性上。 2. 在 SQL 映射文件中使用 ResultMap ```xml <select id="getUserById" resultMap="userMap"> select user_id, user_name, user_password, user_email from user where user_id = #{id} </select> ``` 上面的代码中,我们定义了一个名为 getUserById 的查询语句,它使用了前面定义的 userMap ResultMap,查询结果将会被映射到 User 对象中。 3. 在 Java 代码中使用查询结果 ```java SqlSession sqlSession = sqlSessionFactory.openSession(); User user = sqlSession.selectOne("getUserById", 1); ``` 上面的代码中,我们使用 SqlSession 的 selectOne 方法执行查询语句 getUserById,并将查询结果映射到 User 对象中。 以上就是 ResultMap 的使用方法,它可以让我们更加方便地操作数据库
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

陈亦康

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

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

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

打赏作者

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

抵扣说明:

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

余额充值