MyBatis学习笔记(九) —— 自定义映射resultMap

news/2024/4/25 10:29:02/文章来源:https://blog.csdn.net/fashionjay2019/article/details/129288170

9、自定义映射resultMap

9.1、resultMap处理字段和属性的映射关系

若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射

resultType 是一个具体的类型。

resultMap 是resultMap的标签。

id 是处理主键和属性的映射关系;

result 是处理普通字段和属性的映射关系;

association 是处理多对一

collection 是处理一对多

property 属性

column 字段

javaType 属性的类型

jdbcType 字段的类型

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.EmpMapper"><!--字段名和属性不一致的情况,如何处理映射关系1、为查询的字段设置别名,和属性名保持一致2、当字段符合MySQL的要求使用_,而属性符合java的要求使用驼峰此时可以在MyBatis的核心配置文件中设置一个全局设置,可以自动将下划线映射为驼峰emp_id:empId, emp_name:empName3、使用resultMap自定义映射处理处理多对一的映射关系:① 级联方式处理② association③ 分步查询处理一对多的映射关系① collection② 分步查询--><!--resultMap: 设置自定义的映射关系id: 唯一标识type: 处理映射关系的实体类的类型常用的标签:id: 处理主键和实体类中实现的映射关系result: 处理普通字段和实体类中属性的映射关系association: 处理多对一的映射关系(处理实体类类型的属性)collection: 处理一对多的映射关系(处理集合类型的属性)column: 设置映射关系中的字段名,必须是sql查询出的某个字段property: 设置映射关系中的属性的属性名,必须是处理的实体类类型中的属性名--><resultMap id="empResultMap" type="Emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result></resultMap><select id="getEmpByEmpId" resultMap="empResultMap">select * from t_emp where emp_id = #{empId}</select>
</mapper>

select标签中的resultMap的值对应的是resultMap标签的id

img

9.2、多对一映射处理

处理多对一的映射关系的三种方式:

① 级联方式处理

② association

③ 分步查询

场景模拟:

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

Dept.java

package com.fan.mybatis.pojo;/*** @Date: 2023/02/27* @Author: fan* @Description:*/
public class Dept {private Integer deptId;private String deptName;public Dept() {}public Dept(Integer deptId, String deptName) {this.deptId = deptId;this.deptName = deptName;}public Integer getDeptId() {return deptId;}public void setDeptId(Integer deptId) {this.deptId = deptId;}public String getDeptName() {return deptName;}public void setDeptName(String deptName) {this.deptName = deptName;}@Overridepublic String toString() {return "Dept{" +"deptId=" + deptId +", deptName='" + deptName + '\'' +'}';}
}

Emp.java

package com.fan.mybatis.pojo;/*** @Date: 2023/02/27* @Author: fan* @Description:*/
public class Emp {private Integer empId;private String empName;private Integer age;private String gender;public Dept getDept() {return dept;}public void setDept(Dept dept) {this.dept = dept;}@Overridepublic String toString() {return "Emp{" +"empId=" + empId +", empName='" + empName + '\'' +", age=" + age +", gender='" + gender + '\'' +", dept=" + dept +'}';}private Dept dept;public Emp() {}public Emp(Integer empId, String empName, Integer age, String gender) {this.empId = empId;this.empName = empName;this.age = age;this.gender = gender;}public Integer getEmpId() {return empId;}public void setEmpId(Integer empId) {this.empId = empId;}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 getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}}

EmpMapper.java

/**
* 获取员工以及所对应的部门信息
* @param empId
* @return
*/
Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);

ResultMapTest.java

@Test
public void testGetEmpAndDeptByEmpId(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);Emp emp = mapper.getEmpAndDeptByEmpId(1);System.out.println(emp);
}

9.2.1、方式1:级联方式

第一种方式:使用级联的方式处理多对一的映射关系

EmpMapper.xml

<resultMap id="empAndDeptResultMap" type="Emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result><result column="dept_id" property="dept.deptId"></result><result column="dept_name" property="dept.deptName"></result>
</resultMap><select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">select t_emp.*,t_dept.* from t_emp left join t_dept on t_emp.dept_id = t_dept.dept_id where t_emp.emp_id = #{empId}
</select>

运行测试:

img

9.2.2、方式2:association

第二种方式:使用 association 处理多对一的映射

<resultMap id="empAndDeptResultMap" type="Emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result><!--association: 处理多对一的映射关系(处理实体类类型的属性)property: 设置需要处理映射关系的属性的属性名javaType: 设置要处理的属性的类型--><association property="dept" javaType="Dept"><id column="dept_id" property="deptId"></id><result column="dept_name" property="deptName"></result></association>
</resultMap><select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">select t_emp.*,t_dept.* from t_emp left join t_dept on t_emp.dept_id = t_dept.dept_id where t_emp.emp_id = #{empId}
</select>

9.2.3、方式3:分布查询

第三种方式:使用分布查询处理多对一的映射关系

分布查询:即分步骤查询,比如可以先把员工信息查询出来,然后把员工对应部门的id作为条件,在部门表里查询出员工对应的部门。

多表联查的环境中,通过多个sql语句,一步一步的把需要的数据查询出来。

分布查询可以处理多对一、一对多的映射关系

DeptMapper.java

package com.fan.mybatis.mapper;import com.fan.mybatis.pojo.Dept;
import org.apache.ibatis.annotations.Param;public interface DeptMapper {/*** 通过分步查询查询员工以及所对应的部门信息的第二步* @return*/Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);
}

DeptMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.DeptMapper"><select id="getEmpAndDeptByStepTwo" resultType="Dept">select * from t_dept where dept_id = #{deptId}</select>
</mapper>

EmpMapper.java

/**
* 通过分布查询查询员工以及所对应的部门信息的第一步
* @param empId
* @return
*/
Emp getEmpAndDeptByStep(@Param("empId") Integer empId);

EmpMapper.xml

<resultMap id="empAndDeptByStepResultMap" type="Emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result><!--property: 设置需要处理映射关系的属性的属性名select: 设置分步查询的sql的唯一标识(namespace.sqlId)column: 将查询出来的某个字段作为查询的sql的条件--><association property="dept"select="com.fan.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"column="dept_id"></association>
</resultMap><select id="getEmpAndDeptByStepOne" resultMap="empAndDeptByStepResultMap">select * from t_emp where emp_id = #{empId}
</select>

ResultMapTest.java

@Test
public void testGetEmpAndDeptByStep(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);Emp emp = mapper.getEmpAndDeptByStepOne(1);System.out.println(emp);
}

9.3、延迟加载

分步查询的优点:可以实现延迟加载,延迟加载也可以称为懒加载。

延迟加载可以节约计算机资源,不必要的数据不查询。

但是必须在核心配置文件中设置全局配置信息:

lazyLoadingEnabled: 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载

aggressiveLazyLoading: 当开启时,任何方法的调用都会加载改对象的所有属性。否则,每个属性会按需加载

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

9.3.1全局配置延迟加载

<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>

img

@Test
public void testGetEmpAndDeptByStep(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);Emp emp = mapper.getEmpAndDeptByStepOne(1);System.out.println(emp.getEmpName());
}

运行测试,可以看到只执行了员工的sql

img

如果去掉延迟加载的代码

img

运行测试,可以看到执行了2条sql,员工和部门的sq

img

以上是全局配置加载延迟,对mybatis所有的分步查询都有作用。

9.3.2、设置当前分步查询是否延迟加载

如果让某个分步查询来实现完整的延迟加载,可以添加 fetchType=“eager” 立即加载,或者,fetchType=“lazy” 懒加载

img

img

9.4、一对多映射处理

处理一对多的映射关系

① collection

② 分步查询

场景模拟:

查询某个部门的员工信息,部门对员工是一对多。

9.4.1、方式1:collection

Dept.java

package com.fan.mybatis.pojo;import java.util.List;/*** @Date: 2023/02/27* @Author: fan* @Description:*/
public class Dept {private Integer deptId;private String deptName;private List<Emp> emps;public Dept() {}public Dept(Integer deptId, String deptName) {this.deptId = deptId;this.deptName = deptName;}public Integer getDeptId() {return deptId;}public void setDeptId(Integer deptId) {this.deptId = deptId;}public String getDeptName() {return deptName;}public void setDeptName(String deptName) {this.deptName = deptName;}public List<Emp> getEmps() {return emps;}public void setEmps(List<Emp> emps) {this.emps = emps;}@Overridepublic String toString() {return "Dept{" +"deptId=" + deptId +", deptName='" + deptName + '\'' +", emps=" + emps +'}';}
}

DeptMapper.java

/**
* 查询部门以及部门中的员工信息
* @param deptId
* @return
*/
Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);

collection标签的ofType, 设置集合中的属性

association 标签的javaType,是设置属性的类型

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.DeptMapper"><resultMap id="deptAndEmpResultMap" type="Dept"><id column="dept_id" property="deptId"></id><result column="dept_name" property="deptName"></result><!--ofType: 设置集合类型的属性中存储的数据的类型--><collection property="emps" ofType="Emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="gender" property="gender"></result></collection></resultMap><select id="getDeptAndEmpByDeptId" resultMap="deptAndEmpResultMap">select * from t_dept left join t_emp on t_dept.dept_id = t_emp.dept_id where t_dept.dept_id = #{deptId}</select>
</mapper>

ResultMapTest.java

@Test
public void testGetDeptAndEmpByDeptId(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);Dept dept = mapper.getDeptAndEmpByDeptId(1);System.out.println(dept);
}

运行测试

img

9.4.2、方式2:分步查询

第二种方式:分步查询处理一对多的映射关系

DeptMapper.java

/**
* 通过分步查询查询部门以及部门中的员工信息的第一步
* @param deptId
* @return
*/
Dept getDeptAndEmpByStepOne(@Param("deptId") Integer deptId);

EmpMapper.java

/**
* 通过分步查询查询部门以及部门中的员工信息的第二步
* @param deptId
* @return
*/
List<Emp> getDeptAndEmpByStepTwo(@Param("deptId") Integer deptId);

EmpMapper.xml

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

DeptMapper.xml

<resultMap id="deptAndEmpResultMapByStep" type="Dept"><id column="dept_id" property="deptId"></id><result column="dept_name" property="deptName"></result><collection property="emps"select="com.fan.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"column="dept_id"></collection>
</resultMap><select id="getDeptAndEmpByStepOne" resultMap="deptAndEmpResultMapByStep">select * from t_dept where dept_id = #{deptId}
</select>

ResultMapTest.java

@Test
public void testGetDeptAndEmpByStep(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);Dept dept = mapper.getDeptAndEmpByStepOne(1);System.out.println(dept);
}

运行测试:

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_75934.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HOT100--(3)无重复字符的最长子串

点击查看题目详情 大思路&#xff1a; 创建哈希表&#xff0c;元素类型为<char, int>&#xff0c;分别是字符与其对应下标 用哈希表来存储未重复的子串&#xff0c;若有重复则记录下当前子串最大值maxhashsize 并且开始以相同方法记录下一子串 遍历完成以后&#xff0c…

【项目精选】进销存管理系统的设计与实现(视频+源码+论文)

点击下载源码 1.1研究背景和意义 目前&#xff0c;许多的中小企业普遍存在一个问题&#xff1a;企业的决策者看到的进销存资料及相关报表都是比较繁杂&#xff0c;让本应该一目了然的结果因信息的分散使得产生的结果无法保持一致和完整&#xff0c;造成企业在进销存管理上问题很…

T3 出行云原生容器化平台实践

作者&#xff1a;林勇&#xff0c;就职于南京领行科技股份有限公司&#xff0c;担任云原生负责人&#xff0c;也是公司容器化项目的负责人。主要负责 T3 出行云原生生态相关的所有工作&#xff0c;如服务容器化、多 Kubernetes 集群建设、应用混部、降本增效、云原生可观测性基…

有趣的 Kotlin 0x10:操作符 ..<

操作符 …< ..< 操作符是 Kotlin 在 1.7.20 版本中引入的不包含尾部元素的左闭右开区间操作符。之前我们使用的比较多的操作符可能是 .. 和 until&#xff0c;两者均表示区间&#xff0c;前者是闭区间&#xff0c;后者则表示不包含末端元素的左闭右开区间。 OptIn(Expe…

【微服务】Ribbon实现负载均衡

目录 1.什么是负载均衡 2.自定义负载均衡 3.基于Ribbon实现负载均衡 Ribbon⽀持的负载均衡策略 4.负载均衡原理 源码跟踪 LoadBalancerIntercepor LoadBalancerClient 5.负载均衡策略IRule 总结 1.什么是负载均衡 通俗的讲&#xff0c; 负载均衡就是将负载&#xff…

Java奠基】运算符的讲解与使用

目录 运算符与表达式的使用 算术运算符 隐式转换与强制转换 自增自减运算符 赋值运算符 关系运算符 逻辑运算符 三元运算符 运算符与表达式的使用 运算符是指&#xff1a;对字面量或者变量进行操作的符号。 表达式是指&#xff1a;用运算符把字面量或者变量连接起来&…

使用Geth搭建多节点私有链

使用Geth搭建多节点私有链 步骤 1.编辑初始化配置文件genesis.json {"config": {"chainId": 6668,"homesteadBlock": 0,"eip150Block": 0,"eip150Hash": "0x000000000000000000000000000000000000000000000000000000…

【工具插件类教学】UnityPackageManager私人定制资源工具包

目录 一.UnityPackageManager的介绍 二.package包命名 三.包的布局 四.生成清单文件 五.制作package内功能 六.为您的软件包撰写文档 1.信息的结构 2.文档格式 七.提交上传云端仓库 1.生成程序集文件 2.上传至云端仓库 八.下载使用package包 1.获取包的云端路径 …

Vue3 企业级项目实战:认识 Spring Boot

Vue3 企业级项目实战 - 程序员十三 - 掘金小册Vue3 Element Plus Spring Boot 企业级项目开发&#xff0c;升职加薪&#xff0c;快人一步。。「Vue3 企业级项目实战」由程序员十三撰写&#xff0c;2744人购买https://s.juejin.cn/ds/S2RkR9F/ 越来越流行的 Spring Boot Spr…

NJ+SCU42做Modbus RTU从站

NJSCU42做Modbus RTU从站实验时间&#xff1a;2023.2.28 硬件设备&#xff1a;NJ501-1300&#xff0c;CJ1W-SCU42 软件&#xff1a;Sysmac Studio&#xff0c;Commix串口调试助手 案例简介&#xff1a;发送Modbus RTU命令读取NJ里的数据 1. 系统概述 264 ​ 本次实验使用C…

回暖!“数”说城市烟火气背后

“人间烟火气&#xff0c;最抚凡人心”。在全国各地政策支持以及企业的积极生产运营下&#xff0c;经济、社会、生活各领域正加速回暖&#xff0c;“烟火气”在城市中升腾&#xff0c;信心和希望正在每个人心中燃起。 发展新阶段&#xff0c;高效统筹经济发展和公共安全&#…

[文件操作] File 类的用法和 InputStream, OutputStream 的用法

能吃是不是件幸福的事呢 文章目录前言1. 文件的相关定义2. 文件类型3. Java对文件系统的操作3.1 对文件的基础操作3.2 读文件3.3 写文件前言 从这章开始,我们就开始学文件操作相关的知识了~ 1. 文件的相关定义 1.文件的定义可以从狭义和广义两个方面解释. 狭义: 指硬盘上的文…

进程、线程、协程详解

目录 前言&#xff1a; 一、进程 进程的概念 进程内存空间 二、线程 线程的定义 内核线程 用户线程 内核线程和用户线程的比较 线程的状态 三、协程 协程的定义 协程序相对于线程优势 运用场景 四、线程、协程、进程切换比较 前言&#xff1a; 有时候无法…

原生JS实现拖拽排序

拖拽&#xff08;这两个字看了几遍已经不认识了&#xff09; 说到拖拽&#xff0c;应用场景不可谓不多。无论是打开电脑还是手机&#xff0c;第一眼望去的界面都是可拖拽的&#xff0c;靠拖拽实现APP或者应用的重新布局&#xff0c;或者拖拽文件进行操作文件。 先看效果图&am…

人力资源管理系统

技术&#xff1a;Java、JSP等摘要&#xff1a;在当今的信息化社会&#xff0c;为了更有效率地工作&#xff0c;人们充分利用现在的电子信息技术&#xff0c;在办公室架设起办公服务平台&#xff0c;将人力资源相关信息统一起来管理&#xff0c;帮助管理者有效组织降低成本和加速…

测试2年,当初一起入行的朋友很多月薪20k了,自己却还没过万,到底差在了哪里?

说来奇怪&#xff0c;不管是读书还是工作&#xff0c;都存在一个现象&#xff0c;那就是人比人&#xff0c;比死人。读书的时候&#xff0c;不管是老师还是家长口中&#xff0c;总会有一个“别人家的孩子”。同样&#xff0c;到工作中&#xff0c;领导口中总会有一个“别人的员…

代码随想录算法训练营day46 | 动态规划之背包问题 139.单词拆分

day46139.单词拆分1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp[i]139.单词拆分 题目链接 解题思路&#xff1a;单词就是物品&#xff0c;字符串s就是背包&#xff0c;单词能否组成字符串s&#xff0c;就是问物品能不能把背包装满。…

【微服务】-认识微服务

目录 1.1 单体、分布式、集群 单体 分布式 集群 1.2 系统架构演变 1.2.1 单体应⽤架构 1.2.2 垂直应⽤架构 1.2.3 分布式架构 1.2.4 SOA架构 1.2.5 微服务架构 1.3 微服务架构介绍 微服务架构的常⻅问题 1.4 SpringCloud介绍 1.4.1 SpringBoot和SpringCloud有啥关…

高压放大器知识科普介绍

高压放大器是一种用于放大高压信号的电子设备&#xff0c;具有高压输出&#xff0c;低噪声&#xff0c;高精度&#xff0c;高稳定性&#xff0c;高可靠性&#xff0c;低功耗&#xff0c;低成本等的优点&#xff0c;所以才被广泛应用在磁场探测、电磁脉冲放大、电磁波放大、电磁…

Arduino IDE启动闪退或者运行中闪退

文章目录一、你中了哪一种&#xff1f;1、安装了不符合规格的库文件2、安装了不符合规范的开发板库文件二、解决方案1、轻方案2、全盘重来Arduino IDE启动闪退或者运行中闪退&#xff0c;出现这样的问题&#xff0c;其实不需要思考了&#xff0c;就是运行库配置的问题&#xff…