当前位置: 首页 > 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解…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

xmind转换为markdown

文章目录 解锁思维导图新姿势&#xff1a;将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件&#xff08;ZIP处理&#xff09;2.解析JSON数据结构3&#xff1a;递归转换树形结构4&#xff1a;Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...

JS红宝书笔记 - 3.3 变量

要定义变量&#xff0c;可以使用var操作符&#xff0c;后跟变量名 ES实现变量初始化&#xff0c;因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符&#xff0c;可以创建一个全局变量 如果需要定义…...

深度解析:etcd 在 Milvus 向量数据库中的关键作用

目录 &#x1f680; 深度解析&#xff1a;etcd 在 Milvus 向量数据库中的关键作用 &#x1f4a1; 什么是 etcd&#xff1f; &#x1f9e0; Milvus 架构简介 &#x1f4e6; etcd 在 Milvus 中的核心作用 &#x1f527; 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...

开疆智能Ethernet/IP转Modbus网关连接鸣志步进电机驱动器配置案例

在工业自动化控制系统中&#xff0c;常常会遇到不同品牌和通信协议的设备需要协同工作的情况。本案例中&#xff0c;客户现场采用了 罗克韦尔PLC&#xff0c;但需要控制的变频器仅支持 ModbusRTU 协议。为了实现PLC 对变频器的有效控制与监控&#xff0c;引入了开疆智能Etherne…...