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>

在这里插入图片描述

相关文章
|
3月前
|
SQL XML Java
8、Mybatis-Plus 分页插件、自定义分页
这篇文章介绍了Mybatis-Plus的分页功能,包括如何配置分页插件、使用Mybatis-Plus提供的Page对象进行分页查询,以及如何在XML中自定义分页SQL。文章通过具体的代码示例和测试结果,展示了分页插件的使用和自定义分页的方法。
8、Mybatis-Plus 分页插件、自定义分页
|
3月前
|
SQL Java 测试技术
3、Mybatis-Plus 自定义sql语句
这篇文章介绍了如何在Mybatis-Plus框架中使用自定义SQL语句进行数据库操作。内容包括文档结构、编写mapper文件、mapper.xml文件的解释说明、在mapper接口中定义方法、在mapper.xml文件中实现接口方法的SQL语句,以及如何在单元测试中测试自定义的SQL语句,并展示了测试结果。
3、Mybatis-Plus 自定义sql语句
|
3月前
|
SQL Java Kotlin
MybatisPlus怎么拓展自定义BaseMapper
通过扩展Mybatis-Plus的`BaseMapper`,可以自定义SQL模板以满足特定业务需求。例如,当遇到唯一键冲突而不希望抛出异常时,可使用`INSERT IGNORE`语法。首先,创建`InsertIgnore`类继承`AbstractMethod`并定义`insertIgnore`方法及其SQL模板。接着,在自定义的`UltraBaseMapper`接口中声明`insertIgnore`方法,并让业务Mapper继承此接口。最后,通过`UltraSqlInjector`类将`InsertIgnore`方法注册到Mybatis-Plus插件中。
155 1
|
19天前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
2月前
|
SQL XML Java
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
文章介绍了MyBatis中高级查询的一对多和多对一映射处理,包括创建数据库表、抽象对应的实体类、使用resultMap中的association和collection标签进行映射处理,以及如何实现级联查询和分步查询。此外,还补充了延迟加载的设置和用法。
mybatis复习04高级查询 一对多,多对一的映射处理,collection和association标签的使用
|
2月前
|
SQL XML Java
mybatis复习02,简单的增删改查,@Param注解多个参数,resultType与resultMap的区别,#{}预编译参数
文章介绍了MyBatis的简单增删改查操作,包括创建数据表、实体类、配置文件、Mapper接口及其XML文件,并解释了`#{}`预编译参数和`@Param`注解的使用。同时,还涵盖了resultType与resultMap的区别,并提供了完整的代码实例和测试用例。
mybatis复习02,简单的增删改查,@Param注解多个参数,resultType与resultMap的区别,#{}预编译参数
|
4月前
|
SQL Java 数据库连接
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
94 3
|
1月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
118 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
1月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
56 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
1月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
345 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
下一篇
无影云桌面