Mybatis:自定义映射resultMap(7)
创始人
2024-03-19 16:07:40
0

Mybaits笔记框架:https://blog.csdn.net/qq_43751200/article/details/128154837

自定义映射resultMap

  • 1. Mybatis环境搭建
  • 2. 问题引入
  • 3. 解决表中的字段名和对应类的属性名不一致问题
    • 方式一: 为字段起别名,保持和属性名的一致
    • 方式二:设置全局配置,将下划线_自动映射为驼峰
    • 方式三:通过resultMap设置自定义的映射关系
  • 4. 多对一映射处理
    • 方式一:级联方式处理映射关系
    • 方式二:使用association处理映射关系
    • 方式三:分步查询
  • 5. 一对多映射处理
    • 方式一:使用collection处理映射关系
    • 方式二:分布查询
  • 6.延迟加载

1. Mybatis环境搭建

创建数据库表

-- 创建t_emp表
create table t_emp(eid int NOT NULL PRIMARY KEY, emp_name varchar(20),age int,sex char,email varchar(20),did int
)-- 向t_emp表中插入数据
insert into t_emp(eid, emp_name, age, sex, email, did)
values(1, 'lsm', 23, '男', '1234@qq.com', 1),(2, 'yxy', 23, '男', '1234@qq.com', 2),(3, 'lxy1', 23, '男', '1234@qq.com', 3),(4, 'yxy_lsm', 23, '男', '1234@qq.com', 2),(5, 'lxy', 23, '男', '1234@qq.com', 1)-- 创建t_dept表
create table t_dept(did int,dept_name varchar(20)
)-- 向t_dept表中插入数据
insert into t_dept(did, dept_name) values(1, 'A'),(2, 'B'),(3, 'C')

在这里插入图片描述

在这里插入图片描述

在maven项目中创建对应的实体类(Empt类 和 Dept类)
Emp类

package com.atguigu.pojo;/*** @Author Mr.Lu* @Date 2022/12/2 19:08* @ClassName Emp* @Version 1.0*/
public class Emp {private Integer eid;// t_emp表该列名为emp_nameprivate String empName;private  Integer age;private String sex;private String email;public Emp() {}public Emp(Integer eid, String empName, Integer age, String sex, String email) {this.eid = eid;this.empName = empName;this.age = age;this.sex = sex;this.email = email;}public Integer getEid() {return eid;}public void setEid(Integer eid) {this.eid = eid;}public String getEmpName() {return empName;}public void setEmpName(String empName) {this.empName = empName;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}@Overridepublic String toString() {return "Emp{" +"eid=" + eid +", empName='" + empName + '\'' +", age=" + age +", sex='" + sex + '\'' +", email='" + email + '\'' +'}';}
}

Dept类

package com.atguigu.pojo;/*** @Author Mr.Lu* @Date 2022/12/2 19:07* @ClassName Dept* @Version 1.0*/
public class Dept {private Integer did;// t_dept表该列名为dept_nameprivate String deptName;public Dept() {}public Dept(Integer did, String deptName) {this.did = did;this.deptName = deptName;}public Integer getDid() {return did;}public void setDid(Integer did) {this.did = did;}public String getDeptName() {return deptName;}public void setDeptName(String deptName) {this.deptName = deptName;}@Overridepublic String toString() {return "Dept{" +"did=" + did +", deptName='" + deptName + '\'' +'}';}
}

项目结构

在这里插入图片描述

2. 问题引入

DeptMapper接口

   /*** 获取表t_Emp的所有信息* @return*/List getEmpAll();

DeptMapper接口对应的DeptMapper.xml配置文件

    

测试方法

 @Testpublic void testGetEmpAll(){SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);List empAll = empMapper.getEmpAll();for(Emp emp : empAll){System.out.println(emp);}sqlSession.close();}

在这里插入图片描述

问题描述:经过上图发现empName对应的值都为null,但是t_emp表中的emp_name是存在值的,这是为什么呐?。经过分析产生这种情况的原因在于表中的字段名和对应类的属性名不一致,这个要如何解决呐?

3. 解决表中的字段名和对应类的属性名不一致问题

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

在EmpMapper.xml中为字段起别名

    

测试方法测试:

在这里插入图片描述

方式二:设置全局配置,将下划线_自动映射为驼峰

可以在MyBatis的核心配置文件中的setting标签中,设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中数据时,自动将_类型的字段名转换为驼峰,例如:字段名user_name,设置了mapUnderscoreToCamelCase,此时字段名就会转换为userName。

在mybatis-config.xml核心配置文件中加入对应的setting标签

    

测试方法测试:

在这里插入图片描述

方式三:通过resultMap设置自定义的映射关系

  • resultMap:设置自定义映射

  • 属性:

    • id:表示自定义映射的唯一标识,不能重复

    • type:查询的数据要映射的实体类的类型, 例如User、Emp等实体类型

    • 子标签:

      • id:设置主键的映射关系

      • result:设置普通字段的映射关系

      • 子标签属性:

      • property:设置映射关系中实体类中的属性名

      • column:设置映射关系中表中的字段名

  • 若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射,即使字段名和属性名一致的属性也要映射,也就是全部属性都要列出来

    

测试方法测试:

在这里插入图片描述

4. 多对一映射处理

多个员工对应一个部门:多对一

一个部门对应多个员工:一对多

需求:查询员工信息以及员工所对应的部门信息

public class Emp {  private Integer eid;  private String empName;  private Integer age;  private String sex;  private String email;  private Dept dept;  // 该员工所属的部门//...构造器、get、set方法等
}

方式一:级联方式处理映射关系

EmpMapper接口

  /*** 根据t_emp表的eid查询emp和dept表,最后封装成Emp对象返回* @param eid* @return*/Emp getEmpAndDeptById(Integer eid);

EmpMapper接口对应的EmpMapper.xml配置文件

    

测试方法

 @Testpublic void testGetEmpAndDeptById(){SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);Emp emp = empMapper.getEmpAndDeptById(1);System.out.println(emp);sqlSession.close();}

在这里插入图片描述

方式二:使用association处理映射关系

EmpMapper接口

  /*** 根据t_emp表的eid查询emp和dept表,最后封装成Emp对象返回* @param eid* @return*/Emp getEmpAndDeptById(Integer eid);

EmpMapper接口对应的EmpMapper.xml配置文件

     

测试方法

 @Testpublic void testGetEmpAndDeptById(){SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);Emp emp = empMapper.getEmpAndDeptById(3);System.out.println(emp);sqlSession.close();}

在这里插入图片描述

方式三:分步查询

查询员工信息

EmpMapper接口

 /*** 分布查询,员工及所对应的部门信息* 查询员工信息* @param eid* @return*/Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);

EmpMapper接口对应的EmpMapper.xml配置文件

  • select:设置分布查询的sql的唯一标识(namespace.SQLId或mapper接口的全类名.方法名)
  • column:设置分步查询的条件
 

查询部门信息

DeptMapper接口

 /*** 根据did查询部门信息* @param did* @return*/Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);

DeptMapper接口对应的DeptMapper.xml配置文件


测试方法

    @Testpublic void testGetEmpAndDeptByStepTwoAndOne(){SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);Emp emp = empMapper.getEmpAndDeptByStepOne(4);System.out.println(emp);sqlSession.close();}

在这里插入图片描述

5. 一对多映射处理

多个员工对应一个部门:多对一

一个部门对应多个员工:一对多

Dept类

public class Dept {private Integer did;private String deptName;private List empList;  // 多对一:使用集合的形式//...构造器、get、set方法等// 注意要重写toString方式
}

方式一:使用collection处理映射关系

DeptMapper接口

    /*** 根据did查询部门信息以及其所包含的员工信息* @param did* @return*/Dept getDeptAndEmp(@Param("did") Integer did);

DeptMapper接口对应的DeptMapper.xml配置文件

  

测试方法

    @Testpublic void testGetDeptAndEmp(){SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);Dept dept = deptMapper.getDeptAndEmp(1);System.out.println(dept);sqlSession.close();}

在这里插入图片描述

方式二:分布查询

查询部分信息

DeptMapper接口

 /*** 根据部分的did查询属于该部分的所有员工信息* @param did* @return*/Dept getDeptAndEmpOne(@Param("did") Integer did);

DeptMapper接口对应的DeptMapper.xml配置文件


查询员工信息

EmpMapper接口

 /*** 根据did查询员工集合* @param did* @return*/List getDeptAndEmpTwo(@Param("did") Integer did);

EmpMapper接口对应的EmpMapper.xml配置文件

 

测试方法

@Testpublic void testGetDeptAndEmpOne(){SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);Dept dept = deptMapper.getDeptAndEmpOne(1);System.out.println(dept);sqlSession.close();}

在这里插入图片描述

6.延迟加载

  • 分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:
  • lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
    • aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。 否则,每个属性会按需加载
  • 此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql。此时可通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType=“lazy(延迟加载)|eager(立即加载)”


@Testpublic void testGetEmpAndDeptByStepTwoAndOne(){SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);Emp emp = empMapper.getEmpAndDeptByStepOne(4);System.out.println(emp.getEmpName());sqlSession.close();}
  • 关闭延迟加载,两条SQL语句都运行了
    在这里插入图片描述

  • 开启延迟加载,只运行获取emp的SQL语句
    在这里插入图片描述

    @Testpublic void testGetEmpAndDeptByStepTwoAndOne(){SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);Emp emp = empMapper.getEmpAndDeptByStepOne(4);System.out.println(emp.getEmpName());System.out.println("===============================");System.out.println(emp.getDept());sqlSession.close();}
  • 开启后,需要用到查询dept的时候才会调用相应的SQL语句
    在这里插入图片描述

  • fetchType当开启了全局的延迟加载之后,可以通过该属性手动控制延迟加载的效果,fetchType=“lazy(延迟加载)|eager(立即加载)”



相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...