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处理字段和属性的映射关系 如果字段名和实体类中的属性名不一致的情况下,可以通过resultMap设置自定义映射。 常规写法 /***根据id查询员工信息* param empId* return*/ Emp getEmpByEmpId(Param("empId") Integer empId);<select id…...
Elasticsearch之写入原理以及调优
1、ES 的写入过程 1.1 ES支持四种对文档的数据写操作 create:如果在PUT数据的时候当前数据已经存在,则数据会被覆盖,如果在PUT的时候加上操作类型create,此时如果数据已存在则会返回失败,因为已经强制指定了操作类型…...
python中装饰器的用法
最近发现装饰器是一个非常有意思的东西,很高级! 允许你在不修改函数或类的源代码的情况下,为它们添加额外的功能或修改它们的行为。装饰器本质上是一个接受函数作为参数的可调用对象(通常是函数或类),并返…...
php实现一个简单的MySQL分页
一、案例演示: 二、php 代码 <?php $servername "localhost"; // MySQL服务器名称或IP地址 $username "root"; // MySQL用户名 $password "123456"; // MySQL密码 $dbname "test"; // 要连接…...
算法训练营day23补签
题目1:530. 二叉搜索树的最小绝对差 - 力扣(LeetCode) 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和植物大战僵尸,点CE中文件下面红框位置,选择植物大战僵尸,点击打开 修改冷却: 等冷却完毕,首次扫描0安放植物,再次扫描变动值等冷却完…...
python内置模块之queue(队列)用法
queue是python3的内置模块,创建堆栈队列,用来处理多线程通信,队列对象构造方法如下: queue.Queue(maxsize0) 是先进先出(First In First Out: FIFO)队列。 入参 maxsize 是一个整数,用于设置…...
Spring Security——结合JWT实现令牌的验证与授权
目录 JWT(JSON Web Token) 项目总结 新建一个SpringBoot项目 pom.xml PayloadDto JwtUtil工具类 MyAuthenticationSuccessHandler(验证成功处理器) JwtAuthenticationFilter(自定义token过滤器) W…...
Vector的底层结构剖析
vector的介绍: 1.Vector实现了List接口的集合。 2.Vector的底层也是一个数组,protected Object[] elementData; 3.Vector 是线程同步的,即线程安全,Vector类的操作方法带有Synchronized. 4.在开发中,需要线程同步时࿰…...
实现抖音视频滑动功能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关于文件名 哈喽,大家好。今天我们学习文件系统,我们之前在Linux基础IO中研究的是进程和被打开文件…...
JAVA学习笔记DAY5——Spring_Ioc
文章目录 Bean配置注解方式配置注解配置文件调用组件 注解方法作用域 DI注入注解引用类型自动装配文件结构自动装配实现 基本数据类型DI装配 Bean配置 注解方式配置 类上添加Ioc注解配置文件中告诉SpringIoc容器要检查哪些包 注解仅是一个标记 注解 不同注解仅是为了方便开…...
WPF中的隧道路由和冒泡路由事件
文章目录 简介:一、事件最基本的用法二、理解路由事件 简介: WPF中使用路由事件升级了传统应用开发中的事件,在WPF中使用路由事件能更好的处理事件相关的逻辑,我们从这篇开始整理事件的用法和什么是直接路由,什么是冒…...
ISO七层模型 tcp/ip
OSI七层模型(重点例子) OSI(Open Systems Interconnection)模型,也称为开放系统互连模型,是一个理论模型,由国际标准化组织(ISO)制定,用于描述和理解不同网络…...
MySQL的三种重要的日志
日志 Mysql有三大日志系统 Undo Log(回滚日志):记录修改前的数据,用于事务回滚和 MVCC(多版本并发控制)。 Redo Log(重做日志):记录数据变更,用于崩溃恢复&…...
神经网络学习2
张量(Tensor)是深度学习和科学计算中的基本数据结构,用于表示多维数组。张量可以看作是一个更广义的概念,涵盖了标量、向量、矩阵以及更高维度的数据结构。具体来说,张量的维度可以是以下几种形式: 标量&am…...
Spring Boot整合Redis通过Zset数据类型+定时任务实现延迟队列
😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~ 🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Mi…...
Android入门第69天-AndroidStudio中的Gradle使用国内镜像最强教程
背景 AndroidStudio默认连接的是dl.google的gadle仓库。 每次重新build时: 下载速度慢;等待了半天总时build faild;build到一半connection timeout;即使使用了魔法也难以一次build好;这严重影响了我们的学习、开发效率。 当前网络上的使用国内镜像的教程不全 网上的教程…...
深入浅出 Qt 中 QListView 的设计思想,并掌握大规模、高性能列表的实现方法
在大规模列表控件的显示需求中,必须解决2个问题才能获得较好的性能: 第一就是数据存在哪里, 避免出现数据的副本。第二就是如何展示Item,如何复用或避免创建大量的Item控件。 在QListView体系里,QAbstractListModel解…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
