Mybatis学习之自定义映射resultMap(七)

这里写目录标题

  • 一、准备工作
    • 1、新建maven工程
    • 2、准备两张表
    • 3、建立mapper、pojo、映射文件
      • mapper接口
      • pojo
      • xxxMapper.xml
  • 二、resultMap处理字段和属性的映射关系
    • 1、用起别名的方式保证字段名与属性名一致
    • 2、逐一设置resultMap映射关系
    • 3、配置mapUnderscoreToCamelCase
  • 三、多对一映射关系
    • 1、级联方式处理映射关系
    • 2、使用association处理映射关系
    • 3、分布查询
      • 3.1、查询员工信息
      • 3.2、根据员工所对应的部门id查询部门信息
      • 延迟加载
  • 四、一对多映射关系
    • 1、collection
    • 2、分步查询
      • 1)查询部门信息
      • 2)根据部门id查询部门中所有员工
      • 3)测试类

一、准备工作

1、新建maven工程

新建一个maven工程,具体pom.xml文件以及数据库连接配置文件可以参考之前的笔记。

2、准备两张表

  • 部门员工表
CREATE TABLE `t_emp` (`eid` int(11) NOT NULL AUTO_INCREMENT,`emp_name` varchar(45) DEFAULT NULL,`age` int(11) DEFAULT NULL,`sex` char(1) DEFAULT NULL,`email` varchar(45) DEFAULT NULL,`did` int(11) DEFAULT NULL,PRIMARY KEY (`eid`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COMMENT='部门员工表';
  • 部门机构表
CREATE TABLE `t_dept` (`did` int(11) NOT NULL AUTO_INCREMENT,`dept_name` varchar(45) DEFAULT NULL,PRIMARY KEY (`did`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='部门机构表';

每个表中添加相关参数:

INSERT INTO demo.t_emp (eid, emp_name, age, sex, email, did) VALUES(1, 'Apple', 22, '女', '123456@qq.com', 1);
INSERT INTO demo.t_emp (eid, emp_name, age, sex, email, did) VALUES(2, 'Bela', 33, '女', '123456@qq.com', 1);
INSERT INTO demo.t_emp (eid, emp_name, age, sex, email, did) VALUES(3, 'Cherry', 21, '女', '123456@qq.com', 2);
INSERT INTO demo.t_emp (eid, emp_name, age, sex, email, did) VALUES(4, 'David', 55, '男', '123456@qq.com', 2);
INSERT INTO demo.t_emp (eid, emp_name, age, sex, email, did) VALUES(5, 'Eve', 25, '男', '123456@qq.com', 3);
INSERT INTO demo.t_emp (eid, emp_name, age, sex, email, did) VALUES(6, 'Feman', 34, '男', '123456@qq.com', 3);INSERT INTO demo.t_dept (did, dept_name) VALUES(1, '财务部');
INSERT INTO demo.t_dept (did, dept_name) VALUES(2, '仓储部');
INSERT INTO demo.t_dept (did, dept_name) VALUES(3, '技术部');

3、建立mapper、pojo、映射文件

在这里插入图片描述

mapper接口

public interface EmpMapper {
}
public interface DeptMapper {
}

pojo

Dept pojo:

public class Dept {private Integer did;private String deptName;@Overridepublic String toString() {return "Dept{" +"did=" + did +", 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;}public Dept() {}public Dept(Integer did, String deptName) {this.did = did;this.deptName = deptName;}}

Emp pojo :

public class Emp {private Integer eid;private 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;}@Overridepublic String toString() {return "Emp{" +"eid=" + eid +", empName='" + empName + '\'' +", age=" + age +", sex='" + sex + '\'' +", 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;}}

xxxMapper.xml

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="cn.demo.mybatis.mapper.DeptMapper"></mapper>

EmpMapper.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="cn.demo.mybatis.mapper.EmpMapper"></mapper>

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

若字段名和实体类中的属性名不一致,但是数据库字段名符合数据库的规则(使用_),实体类中的属性名符合Java的规则(使用驼峰)。
这时候可以通过两种方式处理字段名和实体类中的属性的映射关系:

  • 可以通过为字段起别名的方式,保证和实体类中的属性名保持一致
  • 逐一设置resultMap映射关系
  • 可以在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中数据时,自动将_类型的字段名转为驼峰。

1、用起别名的方式保证字段名与属性名一致

和sql中一样,用字段名 属性名 如(emp_name empName)来使二者一致。
在mybatic-config.xml文件中添加别名配置:

    <typeAliases><typeAlias type="cn.demo.mybatis.pojo.Emp" alias="Emp"></typeAlias></typeAliases>
 <!--    List<Emp> getAllEmp();--><select id="getAllEmp" resultType="Emp">select eid, emp_name empName, age, sex, email from t_emp</select>

2、逐一设置resultMap映射关系

在resultMap中,一一对应的设置属性名—>字段名,再在select标签中添加resultMap=“对应resultMap的id”

    <resultMap id="empResultMap" type="cn.demo.mybatis.pojo.Dept"><id property="did" column="did"></id><result property="deptName" column="dept_name"></result></resultMap><select id="getAllDept" resultMap="empResultMap">select * from t_dept</select>

resultMap设置自定义映射关系:
+ id:唯一标识
+ type:映射的实体类型
子标签:
+ id:设置主键的映射关系
+ result:设置其他的映射关系
+ property:设置映射关系中的属性名,即Java实体类类型的属性
+ column:设置映射关系中的字段名,必须是sql语句查询出来的字段名

3、配置mapUnderscoreToCamelCase

在全局配置文件mybatis-config.xml中,加入如下属性配置信息:

<configuration><settings><setting name="mapUnderscoreToCamelCase" value="true"/></settings>
</configuration>

这里设置MyBatis的全局配置,将下划线自动映射成驼峰,比如emp_name -> empName。
注意:settings标签要放在properties后面,否则会报错。

三、多对一映射关系

需要查询一对多,多对一的关系,需要在“一”的pojo中加入多的List<>属性,在“多”的pojo中加入“一”。
也就是说,在Dept类中,需要加入 private List emps; ,在Emp类中,要加入 private Dept dept 。然后给他们各自添加get、set方法,重写构造器和toString()。

1、级联方式处理映射关系

EmpMapper.xml中:

<!--    多对一映射关系,方式一:级联属性赋值--><resultMap id="getEmpAndDeptResultMapOne" 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><result property="dept.did" column="did"></result><result property="dept.deptName" column="dept_name"></result></resultMap><!--        Emp getEmpAndDept(@Param("eid") Integer eid);--><select id="getEmpAndDept" resultMap="getEmpAndDeptResultMapOne">select * from t_emp left join t_depton t_emp.eid = t_dept.did WHERE t_emp.eid = #{eid}</select>

EmpMapper类中

public interface EmpMapper {/*** 查询员工及其所对应的部门信息*/Emp getEmpAndDept(@Param("eid") Integer eid);
}

测试类中:

    @Testpublic void testGetEmpAndDept(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);Emp empAndDept = mapper.getEmpAndDept(3);System.out.println(empAndDept);}

在这里插入图片描述

2、使用association处理映射关系

当一个对象包含一个关联对象时(例如:一个员工emp对应一个部门dept),可以使用映射一对一关系。
EmpMapper.xml:

    <resultMap id="empDeptMap" type="Emp"><id column="eid" property="eid"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="sex" property="sex"></result><result property="email" column="email"></result><association property="dept" javaType="Dept"><id column="did" property="did"></id><result column="dept_name" property="deptName"></result></association></resultMap><!--Emp getEmpAndDeptByEid(@Param("eid") int eid);--><select id="getEmpAndDeptByEid" resultMap="empDeptMap">select emp.*,dept.* from t_emp emp left join t_dept dept on emp.did = dept.did where emp.eid = #{eid}</select>

association标签:

  • property:映射实体类属性名
  • javaType:映射java类型
  • column:映射数据库字段名
  • jdbcType:映射数据库类型

3、分布查询

3.1、查询员工信息

EmpMapper.xml

    <resultMap id="getEmpAndDeptByStepResultMap" 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><result property="did" column="did"></result><association property="dept"select="cn.demo.mybatis.mapper.DeptMapper.getDeptByStep"column="did"fetchType="eager"></association></resultMap><!--     Emp getEmpByStep(@Param("eid") int eid);--><select id="getEmpByStep" resultMap="getEmpAndDeptByStepResultMap">select * from t_emp where eid = #{eid}</select>
  • select:设置了分布查询的sql唯一标识(xml的namespace.SQLId或mapper接口的全类名.方法名)
  • column:分步查询的条件
  • fetchType:通过该属性手动控制延迟加载的效果;lazy表示延迟加载,eager表示立即加载

3.2、根据员工所对应的部门id查询部门信息

DeptMapper.xml:

    <!--        Dept getEmpAndDeptByStepTwo(Integer did);--><!--    分步查询可以实现懒加载--><select id="getDeptByStep" resultType="Dept">select * from t_dept where did = #{did}</select>

延迟加载

分布查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:

  • lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。
  • aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则每个属性都会按需加载。
    lazyLoadingEnabled是控制是否开启懒加载的,而aggressiveLazyLoading是控制关联对象是如何进行懒加载的,比如控制当对关联对象任何的调用都会完全加载所有属性,还是只是按需加载对应属性。
<settings><!--开启延迟加载--><setting name="lazyLoadingEnabled" value="true"/>
</settings>

特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态
此时就可以实现按需求加载,获取的数据是什么,就会执行相应的sql。此时可通过association和 collection中的fetchType属性设置当前的分布查询是否使用延迟加载,fetchType=“lazy(延迟加 载)|eager(立即加载)”。

通过fetchType参数,可以手动控制延迟加载或立即加载,否则根据全局配置的属性决定是延迟加载还是立即加载。

    @Testpublic void testGetEmpByStep() throws IOException {SqlSession sqlSession = SqlSessionUtils.getSqlSession();EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);Emp empAndDept = mapper.getEmpByStep(1);//先打印出emp的元素System.out.println(empAndDept.getEmpName());System.out.println("=====================");//再打印出deptSystem.out.println(empAndDept.getDept());}

当延迟开关打开时候,加载如下:
在这里插入图片描述
当延迟开关关闭时候,加载如下:
在这里插入图片描述

四、一对多映射关系

根据部门id查找部门以及部门中的员工信息。

1、collection

DeptMapper接口:

	 /*** 获取部门以及部门中所有的员工信息*/Dept getDeptAndEmp(@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><!--        Dept getDeptAndEmp(@Param("did") Integer did);--><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>

测试类

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

注意:
这里要在Dept类中,要加入private List emps;

2、分步查询

1)查询部门信息

	Dept getDeptAndEmoByStepOne(@Param("did") Integer did)
<!--    分步查询-->!--    分步查询--><resultMap id="deptAndEmoByStepOneMap" type="Dept"><id property="did" column="did"></id><result property="deptName" column="dept_name"></result><collection property="emps"select="cn.demo.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"column="did"></collection></resultMap><!--        Dept getDeptAndEmoByStepOne(@Param("did") Integer did);--><select id="getDeptAndEmoByStepOne" resultMap="deptAndEmoByStepOneMap">select * from t_dept where did = #{did}</select>

2)根据部门id查询部门中所有员工

List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);
<!--    List<Emp> getDeptAndEmpByStepTwo(@Param("did") Integer did);--><select id="getDeptAndEmpByStepTwo" resultType="Emp">select * from t_emp where did = #{did}</select>

3)测试类

    @Testpublic void testGetDeptAndEmpBySteps() throws IOException {SqlSession sqlSession = SqlSessionUtils.getSqlSession();DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);Dept dept = mapper.getDeptAndEmoByStepOne(2);System.out.println(dept.getDeptName());System.out.println("-----****************======分割线=======-----****************");System.out.println(dept);}

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

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

相关文章

数学学习 | 高数、线代、概率论及数理统计荐书

注&#xff1a;本文为 “数学学习书目推荐” 相关合辑。 略作重排&#xff0c;如有内容异常&#xff0c;请看原文。 高等数学、线性代数及概率论与数理统计领域推荐书目 西湖边的卡夫卡 编辑于 2023-09-19 13:26 7495 人赞同了该回答 数学具有内在的美学属性&#xff0c;但并非…

【LLM实战|langgraph】langgrpah基础

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 langgraph 基础 1. Chatbot实现 # !pip install langchain # !pip install langgraphfrom typing import Annotatedfrom typing_extensions import Typ…

大疆无人机使用eport连接Jetson主板实现目标检测

所需硬件设备如下&#xff1a; 实现原理&#xff1a; 视频流获取&#xff1a;从大疆无人机获取实时视频流。数据传输&#xff1a;将视频流传输至 Jetson 平台。目标检测处理&#xff1a;在 Jetson 上运行目标检测算法对传入的视频帧进行分析 EPort开发套件 大疆官网给出了…

Typora激活与使用

Typora下载 下载地址&#xff1a;Typora 官方中文站 Typora&#xff08;1.9.5及其以前的版本&#xff09; 工具&#xff1a;待补充 流程 1.解压工具 2.将license-gen.exe、node_inject.exe两个文件放于typora安装目录下 3.在typora安装目录下运行cmd&#xff08;可以打开…

图片拆分工具,自定义宫格切割

软件介绍 今天推荐一款实用的图像处理工具——lmage Splitter&#xff0c;支持图像拆分与格式互转功能&#xff0c;无广告干扰&#xff0c;操作简单流畅&#xff0c;满足多样化图片编辑需求。 软件优势 该工具为绿色版设计&#xff0c;无需安装即可直接运行&#xff0c;下载…

23种设计模式解析--创建型模式

创建型模式&#xff08;造物主的智慧&#xff09; 单例模式 模式定义 单例模式&#xff08;Singleton&#xff09;确保一个类仅有一个实例&#xff0c;并提供该实例的全局访问点。核心思想是通过私有化构造函数和静态成员实现受控的对象创建。核心实现要点 私有构造函数&#x…

全面解析软件工程形式化说明技术

一、形式化说明技术概述&#xff1a;从模糊到精确的跨越 在软件工程的发展历程中&#xff0c;需求说明技术始终是确保软件系统成功开发的关键环节。从早期依赖自然语言的非形式化描述&#xff0c;到如今基于数学和逻辑的形式化方法&#xff0c;这一领域经历了从模糊到精确的深…

百度网盘自动启动如何关闭,关闭智能看图

#某度软件引起的奔溃#在日常办公中&#xff0c;有时候双击图片&#xff0c;会自动打开了某度的网盘&#xff0c;很奇怪莫名其妙的为什么会关闭网盘后又自动打开了。如何发现是某度的牛虻软件在搞鬼的&#xff1f;我右键图片&#xff0c;选择打开方式&#xff0c;发现有“智能看…

疏老师-python训练营-Day40训练和测试的规范写法

浙大疏锦行 知识点回顾&#xff1a; 彩色和灰度图片测试和训练的规范写法&#xff1a;封装在函数中展平操作&#xff1a;除第一个维度batchsize外全部展平dropout操作&#xff1a;训练阶段随机丢弃神经元&#xff0c;测试阶段eval模式关闭dropout 作业&#xff1a;仔细学习下测…

【重磅发布】flutter_chen_keyboard -专注于键盘相关功能

flutter_chen_keyboard 一个功能强大且易于使用的 Flutter 键盘增强库&#xff0c;专为提升移动应用的键盘交互体验而设计。 &#x1f4d6; 库简介 flutter_chen_keyboard 是一个专注于键盘相关功能的 Flutter 工具库&#xff0c;旨在为开发者提供更流畅、更智能的键盘交互解决…

idea设置注释--带日期和作者和描述

最终效果 在File Header中添加如下内容&#xff1a; /*** author ${USER}* date ${DATE} ${TIME}* description ${DESCRIPTION}*/${USER}&#xff1a;IDEA 里设置的用户名 ${DATE}&#xff1a;当前日期 ${TIME}&#xff1a;当前时间 可以加自定义变量&#xff0c;比如 ${DESCRI…

【Linux】Socket编程——UDP版

&#x1f4dd;前言&#xff1a; 这篇文章我们来讲讲Linux——udpsocket &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;个人专栏&#xff1a;Linux &#x1f380;CSDN主页 愚润求学 &#x1f304;其他专栏&#xff1a;C学习笔记&#xff0c;C语言入门基础&#…

RabbitMQ面试精讲 Day 14:Federation插件与数据同步

【RabbitMQ面试精讲 Day 14】Federation插件与数据同步 开篇 欢迎来到"RabbitMQ面试精讲"系列第14天&#xff0c;今天我们将深入探讨RabbitMQ Federation插件与跨集群数据同步机制。在分布式系统架构中&#xff0c;如何实现消息队列集群间的数据同步是确保业务连续…

AI编程工具 | Trae介绍

描述需求就可以自动创建可运行的完整项目了&#xff0c;确实很强&#xff01; 终端中的报错信息都可以快速作为上下文输入&#xff0c;点击确认就可以自动修改&#xff0c;贼好使&#xff01; Trae 编程工具详细介绍 一、产品简介 Trae 是字节跳动于 2025 年 1 月 19 日推出的…

【第11话:感知算法基础3】目标检测:深度学习目标检测模型介绍入门及常用模型详解

深度学习目标检测模型介绍入门及常用模型详解 目标检测是计算机视觉的核心任务&#xff0c;需同时完成目标定位&#xff08;输出边界框坐标&#xff09;和目标分类&#xff08;识别类别&#xff09;。深度学习通过端到端训练显著提升了检测精度和效率&#xff0c;主要分为两类架…

稿定科技:多云架构下的 AI 存储挑战与 JuiceFS 实践

稿定科技&#xff08;gaoding.com&#xff09;是一家专注于为企业和个人提供视觉内容创新方案的科技公司&#xff0c;致力于打造全新的设计方式&#xff0c;帮助更多用户轻松掌控设计&#xff0c;创造价值。 随着 AI 技术的加速发展&#xff0c;数据存储和管理成为支撑公司创新…

徘徊识别场景误报率↓77%:陌讯动态时序建模方案实战解析

原创声明本文为原创技术解析&#xff0c;核心技术参数与架构设计参考自《陌讯技术白皮书》&#xff0c;转载请注明来源。一、行业痛点&#xff1a;徘徊识别的现实困境在安防监控领域&#xff0c;徘徊行为识别是保障公共安全的关键技术&#xff08;如商场防盗窃、园区防闯入等场…

C# 通过第三方库INIFileParser管理INI配置文件

C# 通过第三方库INIFileParser管理INI配置文件目录前言一、添加动态库二、添加接口类代码总结前言 很多时候我们是直接调用系统的C库中的GetPrivateProfileString和WritePrivateProfileString接口来实现管理INI文件的&#xff0c;这个接口最久可以追溯到上个世纪80年代&#x…

政府数字化大屏系统 - Flask实现方案

下面我将设计一个基于Flask的政府数字化大屏系统&#xff0c;包含数据可视化、实时监控和统计分析功能&#xff0c;全套代码下载看底部。 设计思路 使用Flask作为后端框架提供数据接口 前端采用响应式设计&#xff0c;适配大屏展示 使用ECharts实现多种数据可视化 模拟实时…

2025年主流开源音视频播放项目深度解析

音视频技术作为多媒体领域的核心支撑&#xff0c;其开源生态在近年来呈现爆发式发展。从底层编解码引擎到跨平台播放器应用&#xff0c;开源项目已形成完整的技术栈&#xff0c;满足从个人娱乐到企业级流媒体服务的全场景需求。本文将深入剖析2025年最具影响力的五大开源音视频…