Mybatis自定义映射--ResultMap

简介: Mybatis自定义映射--ResultMap

ResultType是默认映射,要求字段名要和属性名一致,但是如果我们数据库中的表的字段名和实体类的属性名不一致怎么办呢?这个时候就得用ResultMap来自定义映射

前期准备

先准备两张表,一张是员工表,一张部门表

这里是引用
在这里插入图片描述

1.解决字段名和属性名不一致的情况

1.1方法一 为字段起别名,保持属性名和字段名的一致

当我们写的实体类的属性遵循驼峰,属性名和字段名不一致的话,如果我们使用sql语句的返回值类型用的是resultType的话,是差不多数据的

<select id="getAllEmp" resultType="com.atguigu.mybatis.pojo.Emp">

       select * from t_emp;
    </select>

在这里插入图片描述
我们可以看到empName是没有数据的
解决方法一,sql语句查询的时候使用别名,别名要和属性名一致

> <select id="getAllEmp" resultType="com.atguigu.mybatis.pojo.Emp">
        select eid,emp_name empName,age,sex,email from t_emp;
    </select>

这样子可以查到数据在这里插入图片描述

1.2方法二 设置全局配置,把下划线映射为驼峰

方法二 使用settings进行全局映射

<!--    设置全局属性值-->
    <settings> <!--        把下划线映射为驼峰 emp_name映射成empName,em_pname映射成emPname-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
> <select id="getAllEmp" resultType="com.atguigu.mybatis.pojo.Emp">
--         select eid,emp_name empName,age,sex,email from t_emp;
        select * from t_emp;
    </select>

在这里插入图片描述

1.3方法三 使用ResultMap进行自定义映射

设置字段和属性的关系

<!--    resultMap:设置自定义映射关系
            id:唯一标识
            type:设置映射关系中的实体类类型-->
    <resultMap id="empResultMap" type="Emp">
<!--        id设置主键的映射关系,result设置普通字段的映射关系
property设置映射关系中的属性名,必须是type属性所设置的实体类类型中的属性名
column:设置映射关系中的字段名,必须是sql语句查询出的字段名-->
        <id property="eid" column="eid"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>

    </resultMap>
    <select id="getAllEmp" resultMap="empResultMap">
        select *
        from t_emp;

    </select>

我们都知道数据库中表和表是有关系的,那么它们所对应的实体类,我们要怎样才能使他们有关系呢

2.多对一的映射关系

比如说两张表emp,dept,emp表中有dept表中的部门编号属性,通过这个属性可以查询对应的信息,我们就可以在emp表所对应的实体类中创建对象dept,来表示当前员工所对应的部门对象,我们知道一个部门有多个员工,我们就可以在部门表对应的实体类中设置一个属性,表示员工的集合。

但是这里有一个问题需要我们来解决,我们在mybatis中,通过字段名和属性进行映射,但是,举个例子:我们想要查询员工表的部门编号和部门表的部门编号相等的员工信息,员工表对应的实体类中属性是Dept dept,但是查询出来的结果中,会有部门名字和部门编号,这个时候就无法进行映射,那要怎么解决?接下来给出具体解决方法

2.1方法一 级联属性赋值

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2方法二 通过assocation解决多对一问题

<resultMap id="empAndDeptResultMapTwo" type="Emp">
        <id property="eid" column="eid"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
         <association property="dept" javaType="Dept">
             <id property="deptName" column="dept_name"></id>
             <id property="did" column="did"></id>
         </association>
    </resultMap>
 <select id="getEmpAndDept" resultMap="empAndDeptResultMapTwo">
        SELECT *
        FROM t_emp
                 LEFT JOIN t_dept ON t_emp.did=t_dept.did
        WHERE t_emp.did=2;
    </select>

在这里插入图片描述
我们之前的方法都是通过一条sql语句查询多张表,把数据查询出来,那么我们能不能通过多条sql语句,一步一步查询出来呢?
我们可以先把员工信息查询出来,然后根据员工信息的部门编号把对应的部门信息查询出来,然后把查询出来的部门信息赋值给我们的dept属性,这个方法就是分步查询

2.3方法三 分步查询(用得比较多)

在这里插入图片描述

  <font size=4 color="bluefeafefgrbtnhyjythhrsgaeqwegq">**select**设置分步查询的sql的唯一标识(命名空间.SQLID 或mapper接口的全类名.方法名)
  **column**设置分步查询的条件,比如说我们想要查询部门信息,那么应该是根据部门编号来查询的
        我们查询到了员工信息,那要怎么根据这个信息来查询部门信息呢,那就得根据它们共有的字段did属性也就是部门编号来查询
         在这个sql语句里面我们查询的是员工信息,但是dept的信息要根据另外一条sql语句来查询
         所以这里要通过select属性来说明我们是通过哪一个sql查询出来的
       <resultMap id="empAndDeptByStepResultMapOne" type="Emp">
        <id property="eid" column="eid"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
<!--        column设置分步查询的条件,比如说我们想要查询部门信息,那么应该是根据部门编号来查询的
            我们查询到了员工信息,那要怎么根据这个信息来查询部门信息呢,那就得根据它们共有的字段did属性也就是部门编号来查询
             在这个sql语句里面我们查询的是员工信息,但是dept的信息要根据另外一条sql语句来查询
             所以这里要通过select属性来说明我们是通过哪一个sql查询出来的-->
        <association property="dept"
                     select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
                     column="did"></association>
    </resultMap>
    
    <select id="getEmpAndDeptByStepOne"  resultMap="empAndDeptByStepResultMapOne">
        select * from t_emp where eid= #{eid};
    </select>

在这里插入图片描述

 <select id="getEmpAndDeptByStepTwo" resultType="com.atguigu.mybatis.pojo.Dept">
        select * from t_dept where did= #{did};
    </select>

测试结果
在这里插入图片描述
这个时候大家可能就会有这样的疑惑,我们之前的方法明明可以通过一个SQL语句来解决问题,为什么非得用两个sql语句呢?这样子不是变得更加复杂了吗?其实我们可以发现这两个sql语句分开,各自都是一个功能

分步查询的好处是延迟加载,在mybatis中,延迟加载默认是不开启延迟加载的,我们如果想要实现延迟加载,就必须在核心配置文件中设置全局配置信息(settings标签)。

 <settings>
<!--        把下划线映射为驼峰 emp_name映射成empName,em_pname映射成emPname-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
<!--        开启延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
    </settings>

lazyLoadingEnabled:延迟加载的全局开关,当开启时,所有关联对象(分步查询的第一步,第二步......)都会延迟加载
在这里插入图片描述

开启延迟加载后,我们会发现只执行查询员工sql语句,没有执行dept的sql语句
在这里插入图片描述

如果关闭延迟加载,我们会发现我们本来只是想要查询员工的名字,它还会执行查询部门的sql语句
在这里插入图片描述

aggresslveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每一个属性会按需加载
延迟加载指的是当我们访问哪一些信息,它就会去执行相应的sql,如果没有访问,则没有执行

此时就可以实现按需加载,获取的数据是什么就只会执行相应的sql,此时可以通过assocation和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType="lazy(延迟加载) | eager(立即加载)"

select:设置分步查询的sql唯一标识
column:设置分步查询的条件
fetchtype:当开启了全局的延迟加载以后,可以通过这个属性手动控制延迟加载的效果,如果没有开启延迟加载,那么这个属性可以取的两个值都表示立即加载
在这里插入图片描述

3.一对多的映射关系

3.1方法一 通过collection

在这里插入图片描述

 <resultMap id="deptAndEmpResultMap" type="Dept">
        <id property="did" column="did"></id>
        <result property="deptName" column="dept_name"></result>
        <!--        collection:处理一对多的映射关系-->
        <!--        ofTypeL:表示该属性所对应的集合中存储数据的类型-->
         <collection property="emps"  ofType="Emp">
             <id property="eid" column="eid"></id>
              <result property="empName" column="emp_name"></result>
              <result property="age" column="age"></result>
              <result property="sex" column="sex"></result>
              <result property="email" column="email"></result>

         </collection>
    </resultMap>
    <select id="getDeptAndEmp" resultMap="deptAndEmpResultMap">
        select *
        from t_dept
                 left join t_emp on t_dept.did = t_emp.did
        where t_dept.did = #{did}
    </select>

在这里插入图片描述

  collection:处理一对多的映射关系-->
       ofType:表示该属性所对应的集合中存储数据的类型 

3.2分步查询

先根据部门编号did查询出部门信息,然后再查询出所有员工信息

package com.atguigu.mybatis.mapper;

import com.atguigu.mybatis.pojo.Dept;
import org.apache.ibatis.annotations.Param;

/**
 * @author zengyihong
 * @create 2022--04--03 14:40
 */
public interface DeptMapper {
    
    Dept getDeptAndEmp(@Param("did") Integer did);
    /**
     * 分步查询部门以及部门中所有的员工信息
     * 分步查询第一步:查询部门信息
     */
    Dept getDeptAndEmpByStepOne(@Param("did") Integer did);
}
package com.atguigu.mybatis.mapper;

import com.atguigu.mybatis.pojo.Emp;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @author zengyihong
 * @create 2022--04--03 14:40
 */
public interface EmpMapper {
   
    /**
     * 分步查询部门以及部门中所有的员工信息
     * 分步查询第二步:根据did查询员工信息
     */
    List<Emp> getDeptAndEmpByStepTwo(@Param("did")Integer did)


}

deptmapper.xml

  <resultMap id="deptAndEmpResultMap" type="Dept">
        <id property="did" column="did"></id>
        <result property="deptName" column="dept_name"></result>
        <!--        collection:处理一对多的映射关系-->
        <!--        ofType:表示该属性所对应的集合中存储数据的类型-->
         <collection property="emps"  ofType="Emp">
             <id property="eid" column="eid"></id>
              <result property="empName" column="emp_name"></result>
              <result property="age" column="age"></result>
              <result property="sex" column="sex"></result>
              <result property="email" column="email"></result>

         </collection>
    </resultMap>
    <resultMap id="deptAndEmpByStepResultMap" type="Dept">
        <id property="did" column="did"></id>
        <result property="deptName" column="dept_name"></result>
        <collection property="emps"
                    select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"
                    column="did">

        </collection>

    </resultMap>


    <select id="getDeptAndEmpByStepOne" resultMap="deptAndEmpByStepResultMap">
        select * from t_dept where did = #{did};

    </select>

empmapper.xml

 <select id="getDeptAndEmpByStepTwo" resultType="Emp">
        select *
        from t_emp
        where did = #{did};
    </select>

在这里插入图片描述

相关文章
|
4月前
|
SQL Java 数据库连接
MyBatis 的映射关系
MyBatis 核心功能之一是映射关系,支持一对一、一对多和多对多三种 ORM 映射。通过实体类与配置文件结合,开发者可灵活实现数据关联,提升数据库操作效率。
317 4
|
8月前
|
SQL XML Java
菜鸟之路Day35一一Mybatis之XML映射与动态SQL
本文介绍了MyBatis框架中XML映射与动态SQL的使用方法,作者通过实例详细解析了XML映射文件的配置规范,包括namespace、id和resultType的设置。文章还对比了注解与XML映射的优缺点,强调复杂SQL更适合XML方式。在动态SQL部分,重点讲解了`&lt;if&gt;`、`&lt;where&gt;`、`&lt;set&gt;`、`&lt;foreach&gt;`等标签的应用场景,如条件查询、动态更新和批量删除,并通过代码示例展示了其灵活性与实用性。最后,通过`&lt;sql&gt;`和`&lt;include&gt;`实现代码复用,优化维护效率。
786 5
|
10月前
|
SQL XML Java
七、MyBatis自定义映射resultMap
七、MyBatis自定义映射resultMap
292 6
|
10月前
|
Java 数据库连接 mybatis
MyBatis篇-映射关系(1-1 1-n n-n)
本文介绍了MyBatis中四种常见关系映射的配置方法,包括一对一、一对多、多对一和多对多。**一对一**通过`resultMap`实现属性与字段的映射;**一对多**以用户-角色为例,使用`&lt;collection&gt;`标签关联集合数据;**多对一**以作者-博客为例,利用`&lt;association&gt;`实现关联;**多对多**则通过引入第三方类(如UserForDept)分别在User和Dept类中添加集合属性,并配置对应的`&lt;collection&gt;`标签完成映射。这些方法解决了复杂数据关系的处理问题,提升了开发效率。
|
XML Java 数据库连接
Mybatis映射关系
简介:本文介绍了MyBatis框架中四种常见的关系映射方式,包括一对一、一对多、多对一及多对多。一对一通过简单属性映射实现;一对多通过在主对象中添加集合属性并使用`&lt;collection&gt;`标签映射子对象集合;多对一则利用`&lt;association&gt;`标签在主对象中映射单个子对象;多对多需引入第三方类,分别在两个主对象中添加对方的集合属性,并通过`&lt;collection&gt;`标签实现映射。
243 32
|
7月前
|
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`注解完成整合
1267 1
Spring boot 使用mybatis generator 自动生成代码插件
|
10月前
|
XML Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——基于注解的整合
本文介绍了Spring Boot集成MyBatis的两种方式:基于XML和注解的形式。重点讲解了注解方式,包括@Select、@Insert、@Update、@Delete等常用注解的使用方法,以及多参数时@Param注解的应用。同时,针对字段映射不一致的问题,提供了@Results和@ResultMap的解决方案。文章还提到实际项目中常结合XML与注解的优点,灵活使用两者以提高开发效率,并附带课程源码供下载学习。
804 0
|
12月前
|
前端开发 Java 数据库连接
Java后端开发-使用springboot进行Mybatis连接数据库步骤
本文介绍了使用Java和IDEA进行数据库操作的详细步骤,涵盖从数据库准备到测试类编写及运行的全过程。主要内容包括: 1. **数据库准备**:创建数据库和表。 2. **查询数据库**:验证数据库是否可用。 3. **IDEA代码配置**:构建实体类并配置数据库连接。 4. **测试类编写**:编写并运行测试类以确保一切正常。
585 2
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
654 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
617 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块