当前位置: 首页 > news >正文

mybatis学习--自定义映射resultMap

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

如果字段名和实体类中的属性名不一致的情况下,可以通过resultMap设置自定义映射。

常规写法

/***根据id查询员工信息* @param empId* @return*/
Emp getEmpByEmpId(@Param("empId") Integer empId);<select id="getEmpByEmpId" resultType="emp">select * from emp where emp_id = #{empId}</select>@Test
public void testGetEmpByEmpId(){Emp emp = empMapper.getEmpByEmpId(2);System.out.println(emp);
}

结果:查出的id和name为空值

解决:

⑴可以通过为字段起别名的方式,别名起成和属性名一致。保证字段名和实体类中的属性名一致

<select id="getEmpByEmpId" resultType="emp">select emp_id empId,emp_name empName,age,sex from emp where emp_id = #{empId}
</select>

⑵如果字段名和实体类中的属性名不一致的情况下,但是字段名符合数据库的规则(使用_),实体类中使用的属性名符合java的规则(使用驼峰命名),可以在MyBatis的核心配置文件中设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中的数据时,自动将带下划线“_”的字段名转为驼峰命名

 user_name:userName

 emp_id:empId

mybatis-config.xml文件中

<settings> <!--将数据库字段名的下划线映射为驼峰-->   <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--Emp getEmpByEmpId(@Param("empId") Integer empId);--> 
<select id="getEmpByEmpId" resultType="emp">select * from emp where emp_id = #{empId}  
</select>

⑶使用resutlMap自定义映射处理

<select id="getEmpByEmpId" resultMap="empResultMap">select * from emp where emp_id = #{empId}
</select><resultMap id="empResultMap" type="emp"><id property="empId" column="emp_id"></id><result property="empName" column="emp_name"></result><result property="age" column="age"></result><result property="sex" column="sex"></result>
</resultMap>

1.2一对一映射处理

1、级联方式处理
/** 
* 根据id查询人员信息 
* @param id 
* @return*/ Person findPersonById(@Param("id") Integer id);<!-- Person findPersonById(Integer id);--> <select id="findPersonById" resultMap="IdCardWithPersonResult">SELECT person.*,idcard.codeFROM person,idcardWHERE person.card_id=idcard.id AND person.id=#{id} </select><resultMap id="IdCardWithPersonResult" type="person"><id property="id" column="id"></id><result property="name" column="name"></result><result property="age" column="age"></result><result property="sex" column="sex"></result> <result property="card.id" column="id"></result><result property="card.code" column="code"></result>
</resultMap>@Test
public void testFindPersonById(){Person person = personMapper.findPersonById(2);System.out.println(person);
}
2、Association
<resultMap id="IdCardWithPersonResult2" type="person"><id property="id" column="id"></id><result property="name" column="name"></result><result property="age" column="age"></result><result property="sex" column="sex"></result><!--association 一对一,多对一--><association property="card" javaType="IdCard"><id property="id" column="id"></id><result property="code" column="code"></result></association></resultMap>
3、分步查询
<!--分步查询第一步-->
<!-- Person findPersonById3(@Param("id") Integer id);--><select id="findPersonById3" resultMap="IdCardWithPersonResult3">select * from person where id=#{id}  
</select><resultMap id="IdCardWithPersonResult3" type="person"><id property="id" column="id"></id><result property="name" column="name"></result><result property="age" column="age"></result><result property="sex" column="sex"></result>      <association property="card" javaType="IdCard" column="card_id"                 select="com.qcby.mybatis.mapper.IdCardMapper.findCodeById"> </association>
</resultMap>
<!--分步查询的第二步-->
<!--IdCard findCodeById(@Param("id") Integer id);--><select id="findCodeById" resultType="idcard"> SELECT * from idcard where id=#{id} </select>

1.3多对一映射处理

场景模拟:

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

使用resultMap自定义映射处理处理多对一的映射关系:

1.级联方式处理
/*** 获取员工以及所对应的部门信息* @param empId* @return*/
Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);<select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResultMap">select emp.*,dept.*from empleft join depton emp.dept_id=dept.dept_idwhere emp.emp_id=#{empId}
</select>//此处注意要先写column,在写property
<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="sex" property="sex"></result><result column="dept_id" property="dept.deptId"></result><result column="dept_name" property="dept.deptName"></result>
</resultMap>@Test
public void testGetEmpAndDeptByEmpId(){Emp emp = empMapper.getEmpAndDeptByEmpId(1);System.out.println(emp);
}
 2.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="sex" property="sex"></result><association property="dept" javaType="dept"><id column="dept_id" property="deptId"/><result column="dept_name" property="deptName"/></association>
</resultMap>
3.分步查询
/*** 通过分步查询来查询员工以及所对应的部门信息的第一步* @param empId* @return*/
Emp getEmpAndDeptByStepOne(@Param("empId") Integer empId);<select id="getEmpAndDeptByStepOne" resultMap="empAndDeptResultMap2">select * from emp where emp_id = #{empId}
</select>
<resultMap id="empAndDeptResultMap2" type="emp"><id column="emp_id" property="empId"></id><result column="emp_name" property="empName"></result><result column="age" property="age"></result><result column="sex" property="sex"></result><association property="dept" column="dept_id"select="com.qc.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"></association>
</resultMap>
/*** 通过分步查询来查询员工以及所对应的部门信息的第二步* @param deptId* @return*/
Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);<!--Dept getEmpAndDeptByStepTwo(@Param("deptId") Integer deptId);-->
<select id="getEmpAndDeptByStepTwo" resultType="dept">select * from dept where dept_id='${deptId}'
</select>

测试:

@Test
public void testGetEmpAndDeptByStepOne(){Emp emp = empMapper.getEmpAndDeptByStepOne(3);System.out.println(emp);
}

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

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

aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载,此时就可以实现按需加载,获取的数据是什么,就会执行相应的sql语句

此时可以通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType=“lazy(延迟加载)|eager(立即加载)”

1.4一对多映射处理 

没有级联方式的查询,只有collection 和分步查询

8.4.1 collection

dept接口

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

dept映射文件中

<!--Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);--> <select id="getDeptAndEmpByDeptId" resultMap="deptAndEmpResultMap">SELECT *    FROM dept    LEFT JOIN emp    ON dept.dept_id=emp.dept_id    WHERE dept.dept_id=#{deptId} </select><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="sex" property="sex"></result></collection>
</resultMap>

测试方法

@Test  public  void testGetDeptAndEmpByDeptId(){Dept dept = deptMapper.getDeptAndEmpByDeptId(1);System.out.println(dept);
}
1.4.2分步查询

员工表设计

 部门表设计

⑴查询部门信息

/*** 通过分步查询进行查询部门及部门中的员工信息的第一步:查询部门信息* @param deptId* @return 
*/ Dept getDeptAndEmpBySetpOne(@Param("deptId") Integer deptId);<!-- Dept getDeptAndEmpBySetpOne(@Param("deptId") Integer deptId);--><select id="getDeptAndEmpBySetpOne" resultMap="deptAndEmpResultMapByStep">select * from dept where dept_id = #{deptId}  </select><resultMap id="deptAndEmpResultMapByStep" type="dept"><id column="dept_id" property="deptId"></id><result column="dept_name" property="deptName"></result><collection property="emps" column="dept_id"                select="com.qcby.mybatis.mapper.EmpMapper.getDeptAndEmpBySetpTwo">
</collection>
</resultMap>

⑵查询员工信息

/*** 通过分步查询进行查询部门及部门中的员工信息的第二步:查询员工信息* @param deptId* @return 
*/  
List<Emp> getDeptAndEmpBySetpTwo(@Param("deptId")Integer deptId);<!-- List<Emp> getDeptAndEmpBySetpTwo(@Param("deptId")Integer deptId);--><select id="getDeptAndEmpBySetpTwo" resultType="emp">select  * from  emp where dept_id = #{deptId} </select>

⑶测试方法

@Testpublic void testGetDeptAndEmpBySetp(){Dept dept = deptMapper.getDeptAndEmpBySetpOne(2);System.out.println(dept);
}

1.5多对多映射关系

商品和订单两者之间的关系  一种商品存在多个订单中、一个订单存在多个商品

创建一个中间表来描述两者的关联关系

商品的表结构

订单的表结构

中间表

1.5.3 分步查询

⑴查询订单信息

/*** 通过分步查询进行查询订单以及订单中的商品信息的第一步* @param id 
* @return*/  List<Orders>  findOrdersWithProduct2(@Param("id") Integer id);
<!-- List<Orders>  findOrdersWithProduct2(@Param("id") Integer id);--><select id="findOrdersWithProduct2" resultMap="OrdersWithProductResult2">select * from  orders where id = #{id} </select><resultMap id="OrdersWithProductResult2" type="orders"><id column="id" property="id"></id><result column="number" property="number"></result><collection property="productList" column="id" ofType="product"                select="com.qcby.mybatis.mapper.ProductMapper.findProductById"> </collection>
</resultMap>

⑵查询商品信息

/*** 通过分步查询进行查询订单以及订单中的商品信息的第二步* @param id* @return */List<Product> findProductById(@Param("id") Integer id);<!--List<Product> findProductById(@Param("id") Integer id);--><select id="findProductById" resultType="product">select * from product where id in(select product_id from ordersitem where orders_id = #{id}    )  
</select>

⑶测试

@Testpublic void testFindOrdersWithProduct2(){ List<Orders> orders = ordersMapper.findOrdersWithProduct2(1);    orders.forEach(System.out::println);
}

相关文章:

mybatis学习--自定义映射resultMap

1.1、resultMap处理字段和属性的映射关系 如果字段名和实体类中的属性名不一致的情况下&#xff0c;可以通过resultMap设置自定义映射。 常规写法 /***根据id查询员工信息* param empId* return*/ Emp getEmpByEmpId(Param("empId") Integer empId);<select id…...

Elasticsearch之写入原理以及调优

1、ES 的写入过程 1.1 ES支持四种对文档的数据写操作 create&#xff1a;如果在PUT数据的时候当前数据已经存在&#xff0c;则数据会被覆盖&#xff0c;如果在PUT的时候加上操作类型create&#xff0c;此时如果数据已存在则会返回失败&#xff0c;因为已经强制指定了操作类型…...

python中装饰器的用法

最近发现装饰器是一个非常有意思的东西&#xff0c;很高级&#xff01; 允许你在不修改函数或类的源代码的情况下&#xff0c;为它们添加额外的功能或修改它们的行为。装饰器本质上是一个接受函数作为参数的可调用对象&#xff08;通常是函数或类&#xff09;&#xff0c;并返…...

php实现一个简单的MySQL分页

一、案例演示&#xff1a; 二、php 代码 <?php $servername "localhost"; // MySQL服务器名称或IP地址 $username "root"; // MySQL用户名 $password "123456"; // MySQL密码 $dbname "test"; // 要连接…...

算法训练营day23补签

题目1&#xff1a;530. 二叉搜索树的最小绝对差 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int reslut INT_MAX;TreeNode* pre NULL;void trackingback(TreeNode* node) {if(node NULL) return;trackingback(node->left);if(pre ! NULL) {reslut…...

国密SM2JS加密后端解密

1.前端加密 前端加密开源库 sm-crypto 1.1 传统web,下载 sm-crypto 进行打包为 dist/sm2.js 相关打包命令 npm install --save sm-crypto npm install npm run prepublish在web页面引用打包后的文件 <script type"text/javascript" src"<%path %>…...

Cheat Engine.exe修改植物大战僵尸阳光与冷却

Cheat Engine.exe修改植物大战僵尸阳光与冷却 打开Cheat Engine.exe和植物大战僵尸&#xff0c;点CE中文件下面红框位置&#xff0c;选择植物大战僵尸&#xff0c;点击打开 修改冷却&#xff1a; 等冷却完毕&#xff0c;首次扫描0安放植物&#xff0c;再次扫描变动值等冷却完…...

python内置模块之queue(队列)用法

queue是python3的内置模块&#xff0c;创建堆栈队列&#xff0c;用来处理多线程通信&#xff0c;队列对象构造方法如下&#xff1a; queue.Queue(maxsize0) 是先进先出&#xff08;First In First Out: FIFO&#xff09;队列。 入参 maxsize 是一个整数&#xff0c;用于设置…...

Spring Security——结合JWT实现令牌的验证与授权

目录 JWT&#xff08;JSON Web Token&#xff09; 项目总结 新建一个SpringBoot项目 pom.xml PayloadDto JwtUtil工具类 MyAuthenticationSuccessHandler&#xff08;验证成功处理器&#xff09; JwtAuthenticationFilter&#xff08;自定义token过滤器&#xff09; W…...

Vector的底层结构剖析

vector的介绍&#xff1a; 1.Vector实现了List接口的集合。 2.Vector的底层也是一个数组,protected Object[] elementData; 3.Vector 是线程同步的&#xff0c;即线程安全&#xff0c;Vector类的操作方法带有Synchronized. 4.在开发中&#xff0c;需要线程同步时&#xff0…...

实现抖音视频滑动功能vue3+swiper

首先,你需要安装和引入Swiper库。可以使用npm或者yarn进行安装。 pnpm install swiper然后在Vue组件中引入Swiper库和样式。 // 导入Swiper组件和SwiperSlide组件,用于创建轮播图 import {Swiper, SwiperSlide } from swiper/vue; // 导入Swiper的CSS样式,确保轮播图的正确…...

Linux文件系统【真的很详细】

目录 一.认识磁盘 1.1磁盘的物理结构 1.2磁盘的存储结构 1.3磁盘的逻辑存储结构 二.理解文件系统 2.1如何管理磁盘 2.2如何在磁盘中找到文件 2.3关于文件名 哈喽&#xff0c;大家好。今天我们学习文件系统&#xff0c;我们之前在Linux基础IO中研究的是进程和被打开文件…...

JAVA学习笔记DAY5——Spring_Ioc

文章目录 Bean配置注解方式配置注解配置文件调用组件 注解方法作用域 DI注入注解引用类型自动装配文件结构自动装配实现 基本数据类型DI装配 Bean配置 注解方式配置 类上添加Ioc注解配置文件中告诉SpringIoc容器要检查哪些包 注解仅是一个标记 注解 不同注解仅是为了方便开…...

WPF中的隧道路由和冒泡路由事件

文章目录 简介&#xff1a;一、事件最基本的用法二、理解路由事件 简介&#xff1a; WPF中使用路由事件升级了传统应用开发中的事件&#xff0c;在WPF中使用路由事件能更好的处理事件相关的逻辑&#xff0c;我们从这篇开始整理事件的用法和什么是直接路由&#xff0c;什么是冒…...

ISO七层模型 tcp/ip

OSI七层模型&#xff08;重点例子&#xff09; OSI&#xff08;Open Systems Interconnection&#xff09;模型&#xff0c;也称为开放系统互连模型&#xff0c;是一个理论模型&#xff0c;由国际标准化组织&#xff08;ISO&#xff09;制定&#xff0c;用于描述和理解不同网络…...

MySQL的三种重要的日志

日志 Mysql有三大日志系统 Undo Log&#xff08;回滚日志&#xff09;&#xff1a;记录修改前的数据&#xff0c;用于事务回滚和 MVCC&#xff08;多版本并发控制&#xff09;。 Redo Log&#xff08;重做日志&#xff09;&#xff1a;记录数据变更&#xff0c;用于崩溃恢复&…...

神经网络学习2

张量&#xff08;Tensor&#xff09;是深度学习和科学计算中的基本数据结构&#xff0c;用于表示多维数组。张量可以看作是一个更广义的概念&#xff0c;涵盖了标量、向量、矩阵以及更高维度的数据结构。具体来说&#xff0c;张量的维度可以是以下几种形式&#xff1a; 标量&am…...

Spring Boot整合Redis通过Zset数据类型+定时任务实现延迟队列

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…...

Android入门第69天-AndroidStudio中的Gradle使用国内镜像最强教程

背景 AndroidStudio默认连接的是dl.google的gadle仓库。 每次重新build时: 下载速度慢;等待了半天总时build faild;build到一半connection timeout;即使使用了魔法也难以一次build好;这严重影响了我们的学习、开发效率。 当前网络上的使用国内镜像的教程不全 网上的教程…...

深入浅出 Qt 中 QListView 的设计思想,并掌握大规模、高性能列表的实现方法

在大规模列表控件的显示需求中&#xff0c;必须解决2个问题才能获得较好的性能&#xff1a; 第一就是数据存在哪里&#xff0c; 避免出现数据的副本。第二就是如何展示Item&#xff0c;如何复用或避免创建大量的Item控件。 在QListView体系里&#xff0c;QAbstractListModel解…...

答辩 PPT 还在熬夜手搓?Paperxie AI 一键救场,毕业季不熬无用夜

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AI PPThttps://www.paperxie.cn/ppt/createhttps://www.paperxie.cn/ppt/create 当论文终稿尘埃落定&#xff0c;本以为能松一口气&#xff0c;却发现答辩 PPT 成了压垮心态的最后一根稻草。对着空白页面不…...

Gemini3.1Pro解决新媒体小编选题难痛点

做新媒体的小编&#xff0c;最怕的不是写&#xff0c;而是“今天写什么”。 选题总是来得很急&#xff0c;热点总是变化很快&#xff0c;账号又要求持续更新&#xff0c;结果就是&#xff1a;内容压力大、时间不够用、框架搭不出来。如果你每天都在追热点、找角度、写标题、搭结…...

【Flutter for open harmony 】Flutter三方库Dio网络请求+熬夜记录列表的鸿蒙化适配与实战指南

【Flutter for open harmony 】Flutter三方库Dio网络请求熬夜记录列表的鸿蒙化适配与实战指南 欢迎加入开源鸿蒙跨平台社区&#xff1a;https://openharmonycrossplatform.csdn.net 大家好&#xff0c;我是ShineQiu&#xff0c;上海某高校计算机科学与技术专业大二在读学生。这…...

基于STC89C51单片机的多波形信号发生器设计与Proteus仿真

基于STC89C51单片机的多波形信号发生器设计与Proteus仿真 摘 要 随着电子技术和集成电路的飞速发展&#xff0c;信号发生器作为电子测量领域的基础设备&#xff0c;其性能和智能化水平不断提升。本设计以STC89C51单片机为控制核心&#xff0c;设计了一款多波形信号发生器。系统…...

ARM RAS架构:错误记录与注入机制详解

1. ARM RAS架构概述在现代计算系统中&#xff0c;可靠性、可用性和可服务性(Reliability, Availability, and Serviceability, RAS)已成为关键设计指标。ARM架构通过一系列硬件机制实现这些特性&#xff0c;其中错误记录与注入机制是核心组成部分。这套机制允许系统检测、记录硬…...

ARM架构CNTHP_CTL_EL2寄存器详解与虚拟化应用

1. ARM架构中的CNTHP_CTL_EL2寄存器深度解析在ARMv8-A架构的虚拟化环境中&#xff0c;定时器管理是Hypervisor实现高效资源调度和时间隔离的关键组件。作为EL2特权级的物理定时器控制寄存器&#xff0c;CNTHP_CTL_EL2为虚拟化软件提供了精确的计时控制能力。本文将深入剖析该寄…...

金融文档实时检索难?电商SKU模糊匹配慢?DeepSeek垂直搜索3类高价值场景落地,附可复用Prompt工程模板

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;金融文档实时检索难&#xff1f;电商SKU模糊匹配慢&#xff1f;DeepSeek垂直搜索3类高价值场景落地&#xff0c;附可复用Prompt工程模板 三大典型业务痛点与DeepSeek-R1适配逻辑 传统向量检索在专业领…...

HDiffPatch实际应用案例:APK文件差异化和Android应用商店优化

HDiffPatch实际应用案例&#xff1a;APK文件差异化和Android应用商店优化 【免费下载链接】HDiffPatch a C\C library and command-line tools for Diff & Patch between binary files or directories(folder); cross-platform; runs fast; create small delta/differentia…...

【Kanzi 资源系统完全笔记】

一、Resource 的类层次结构Kanzi 中所有资源&#xff08;Resource&#xff09;都继承自 Object 基类。下图是常见的资源继承体系&#xff08;根据图片整理&#xff09;&#xff1a;Object└── Resource├── GPUResource # 位于 GPU 显存中的资源&#xff08;纹理、…...

保姆级教程:用MNN在Android上部署你的第一个图像分类App(从模型转换到实时摄像头识别)

从零构建Android端智能图像分类应用&#xff1a;MNN实战全流程解析 在移动互联网时代&#xff0c;将AI能力嵌入移动端应用已成为提升用户体验的关键。想象一下这样的场景&#xff1a;用户打开手机就能实时识别植物种类、辨别商品真伪&#xff0c;或是自动分类相册中的照片——这…...