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

【Mybatis】useGeneratedKeys实战:三种配置方式与主键回填陷阱解析

1. 什么是useGeneratedKeys如果你用过MySQL这类支持自增主键的数据库肯定遇到过这样的场景插入一条记录后需要立刻获取数据库自动生成的主键ID。比如用户注册后要跳转到个人中心页面这时候就需要拿到新用户的ID。Mybatis的useGeneratedKeys参数就是为解决这个问题而生的。官方文档对它的定义是允许JDBC支持自动生成主键需要驱动兼容。简单来说当数据库支持自动生成主键如MySQL的AUTO_INCREMENT设置这个参数为true后执行插入操作时Mybatis会通过JDBC驱动把生成的主键值取回来。我刚开始用这个功能时以为返回值就是主键ID结果踩了个坑——实际上返回值是影响行数真正的主键被注入到了参数对象的属性里这个我们后面会详细讲。2. 三种配置方式详解2.1 全局配置方式在mybatis-config.xml配置文件中可以通过settings标签设置全局参数。这是我最早接触的配置方式configuration settings !-- 其他配置... -- setting nameuseGeneratedKeys valuetrue / /settings /configuration这种配置有个特点它只对接口映射器Insert注解方式生效对XML映射器无效。我在项目中发现这个限制时还挺困惑的后来查源码才知道这是Mybatis的故意设计。实际开发中如果团队统一使用接口映射器这种方式最省事但如果混用两种方式建议配合局部配置使用。全局配置的优先级最低会被局部配置覆盖。比如你在全局开启了useGeneratedKeys但在某个Insert方法上显式设置为false最终会以false为准。2.2 XML映射器配置在Mapper.xml文件中可以直接在insert标签中配置insert idinsertUser parameterTypeUser useGeneratedKeystrue keyPropertyid keyColumnuser_id INSERT INTO user(name, age) VALUES(#{name}, #{age}) /insert这里三个参数需要特别注意useGeneratedKeystrue启用主键回填keyPropertyid指定接收主键的Java对象属性名keyColumnuser_id指定数据库主键列名可省略默认与keyProperty相同我曾经遇到过一个问题数据库主键列叫user_id但实体类属性叫id。如果只设置keyPropertyid主键无法正确回填。后来加上keyColumnuser_id就解决了。所以当字段名和属性名不一致时这两个参数都需要明确指定。2.3 接口映射器配置使用注解方式时可以通过Options配置Options(useGeneratedKeys true, keyProperty id, keyColumn id) Insert(INSERT INTO user(name, age) VALUES(#{name}, #{age})) int insertUser(User user);这种方式的优先级最高会覆盖全局配置。我在Spring Boot项目中特别喜欢用这种写法因为足够简洁。但要注意一个细节如果参数是多个对象的组合比如用Param注解keyProperty需要写成user.id这样的形式。3. 配置优先级与作用范围三种配置方式的作用范围和优先级经常让人混淆我用一个表格来总结配置方式作用范围优先级是否影响XML映射器是否影响接口映射器全局配置所有接口映射器低否是XML映射器配置当前insert语句中是否接口映射器配置当前方法高否是特别要注意的是XML映射器配置和接口映射器配置互不影响。也就是说你在XML里配的useGeneratedKeys不会影响到注解方式反之亦然。这个设计让两种方式可以独立工作但也容易造成 confusion。4. 主键回填的常见坑4.1 返回值误解陷阱这是我踩过的典型坑看这段代码// Mapper接口 int insertUser(User user); // 调用代码 User user new User(张三, 25); int id userMapper.insertUser(user); // 你以为id是主键错了这里的返回值其实是影响行数通常是1而不是主键ID。正确的获取方式是userMapper.insertUser(user); Long id user.getId(); // 这才是真正的主键4.2 批量插入的特殊处理批量插入时useGeneratedKeys的用法有所不同insert idbatchInsert useGeneratedKeystrue keyPropertyid INSERT INTO user(name, age) VALUES foreach collectionlist itemitem separator, (#{item.name}, #{item.age}) /foreach /insert调用代码ListUser users Arrays.asList( new User(张三, 25), new User(李四, 30) ); userMapper.batchInsert(users); // 插入后每个user对象的id都会被自动填充 users.forEach(user - System.out.println(user.getId()));注意MySQL支持批量插入回填主键但某些数据库可能不支持。此外批量操作时返回的影响行数是总行数不是主键。4.3 复合主键的处理当表使用复合主键时useGeneratedKeys的配置要特别注意insert idinsert useGeneratedKeystrue keyPropertyid.id1, id.id2 INSERT INTO some_table(col1, col2) VALUES(#{val1}, #{val2}) /insert这里keyProperty需要指定多个属性用逗号分隔。对应的Java对象要有嵌套的主键对象public class Entity { private PK id; // getters setters } public class PK { private Long id1; private String id2; // getters setters }5. 原理剖析与最佳实践5.1 底层实现机制useGeneratedKeys背后是JDBC的Statement.RETURN_GENERATED_KEYS机制。Mybatis执行插入后会调用getGeneratedKeys()方法获取数据库生成的主键。不同数据库驱动实现这个机制的方式不同MySQL通过SELECT LAST_INSERT_ID()获取PostgreSQL通过RETURNING子句获取Oracle通常通过序列(sequence)实现5.2 性能考量开启useGeneratedKeys会有轻微的性能开销因为需要额外获取主键。但在大多数应用中这个开销可以忽略不计。如果确实需要极致性能可以考虑以下优化批量操作时使用专门的批量API如ExecutorType.BATCH对于不需要获取主键的插入操作显式设置为false在高并发场景下考虑使用UUID等客户端生成的主键5.3 兼容性问题虽然大多数主流数据库都支持但仍有几点需要注意不同数据库对批量插入获取主键的支持程度不同某些旧版本驱动可能有兼容性问题非自增主键如UUID不需要使用此功能6. 替代方案比较除了useGeneratedKeysMybatis还提供了其他获取主键的方式6.1 selectKey方式insert idinsert selectKey keyPropertyid resultTypelong orderAFTER SELECT LAST_INSERT_ID() /selectKey INSERT INTO user(name, age) VALUES(#{name}, #{age}) /insert这种方式更灵活可以在插入前或插入后执行也适用于非自增主键的场景。但缺点是写法稍显复杂且数据库方言需要手动处理。6.2 数据库函数方式比如在PostgreSQL中可以直接使用RETURNING子句insert idinsert INSERT INTO user(name, age) VALUES(#{name}, #{age}) RETURNING id /insert这种方式最直接但缺乏跨数据库兼容性。7. 实战建议根据多年项目经验我总结出以下建议单一项目保持风格统一要么全部用XML配置要么全部用注解配置避免混用导致混乱明确指定keyProperty和keyColumn即使名称相同也建议显式声明提高代码可读性添加清晰的注释特别是批量操作和复合主键等特殊情况单元测试验证编写测试用例验证主键是否正确回填关注日志输出Mybatis的DEBUG日志会显示是否启用了获取主键功能一个完整的示例项目结构可以这样组织src/ ├── main/ │ ├── java/ │ │ └── com/ │ │ └── example/ │ │ ├── model/ # 实体类 │ │ ├── mapper/ # Mapper接口 │ │ └── service/ │ └── resources/ │ ├── mybatis/ │ │ ├── mybatis-config.xml # 全局配置 │ │ └── mapper/ # XML映射文件 └── test/ # 测试代码

相关文章:

【Mybatis】useGeneratedKeys实战:三种配置方式与主键回填陷阱解析

1. 什么是useGeneratedKeys? 如果你用过MySQL这类支持自增主键的数据库,肯定遇到过这样的场景:插入一条记录后,需要立刻获取数据库自动生成的主键ID。比如用户注册后要跳转到个人中心页面,这时候就需要拿到新用户的ID。…...

GPLT天梯赛L2-L3难题复盘:从‘三点共线’超时到‘胖达的山头’差分,我的C++踩坑与优化实录

GPLT天梯赛L2-L3难题复盘:从‘三点共线’超时到‘胖达的山头’差分,我的C踩坑与优化实录 参加算法竞赛就像在迷宫中寻找出口,每一次错误的转弯都是通往正确答案的必经之路。去年GPLT天梯赛中,我在L2和L3级别的题目上经历了从超时崩…...

百元级专业无人机开发:ESP-Drone如何用开源方案突破技术壁垒

百元级专业无人机开发:ESP-Drone如何用开源方案突破技术壁垒 【免费下载链接】esp-drone Mini Drone/Quadcopter Firmware for ESP32 and ESP32-S Series SoCs. 项目地址: https://gitcode.com/GitHub_Trending/es/esp-drone 在无人机技术快速发展的今天&…...

Lychee-Rerank在专利检索中的应用:权利要求书-现有技术文档语义匹配

Lychee-Rerank在专利检索中的应用:权利要求书-现有技术文档语义匹配 1. 工具简介与核心价值 Lychee-Rerank是一个专门为检索场景设计的本地化相关性评分工具,它基于先进的Qwen2.5-1.5B模型开发,能够精准评估查询语句与候选文档之间的语义匹…...

OrCAD与Ultra Librarian协同:高效构建PCB封装库的实战指南

1. 为什么需要OrCAD与Ultra Librarian协同工作 画PCB板最头疼的事情之一就是给各种芯片找封装。我刚入行时曾经花了一整天手动绘制一个QFN封装,结果因为小数点看错导致整个批次板子报废。现在有了Ultra Librarian这种"封装淘宝",配合OrCAD的自…...

Rancher 2.x 离线部署避坑指南:如何用一条awk命令精准筛选所需镜像版本

Rancher 2.x 离线部署中的镜像版本精准筛选实战 在离线环境中部署Rancher集群时,镜像版本管理往往成为最容易被忽视却又至关重要的环节。我曾亲眼见证一个团队因为使用了错误的Calico镜像版本,导致整个集群网络策略失效,排查三天才发现问题根…...

用Gazebo+ROS Melodic搭建你的第一个无人机自主导航仿真环境(FastPlanner规划+VINS定位)

从零构建Gazebo无人机仿真环境:FastPlanner与VINS的实战融合 当第一次看到无人机在仿真环境中自主避障飞行时,那种程序具象化的震撼至今难忘。作为机器人领域最激动人心的应用之一,自主导航系统正从实验室走向工业现场,而仿真环境…...

用HDLbits练手计数器?我总结了这5种经典模式帮你搞定FPGA面试题

5种计数器设计模式:从HDLbits到FPGA面试的实战指南 在数字电路设计中,计数器就像面包和黄油一样基础而重要。无论是简单的时序控制还是复杂的时钟管理,计数器都扮演着关键角色。对于准备FPGA相关岗位面试的工程师来说,掌握各种计数…...

FLAC3D动力时程分析在边坡抗震设计中的关键应用

1. FLAC3D动力时程分析的核心价值 边坡工程在地震作用下的稳定性分析一直是岩土工程领域的难点。传统静力分析方法难以准确反映地震动荷载的动态特性,而FLAC3D的动力时程分析功能恰好填补了这一技术空白。我曾在西南某水电站边坡项目中实测对比发现,动力…...

FinBERT金融情感分析:如何用AI模型洞察市场情绪变化

FinBERT金融情感分析:如何用AI模型洞察市场情绪变化 【免费下载链接】finbert 项目地址: https://ai.gitcode.com/hf_mirrors/ai-gitcode/finbert FinBERT是一款专门为金融文本设计的预训练NLP模型,能够准确分析财经新闻、研报和社交媒体中的情感…...

PKHeX自动合法性插件:3分钟搞定宝可梦数据合规验证

PKHeX自动合法性插件:3分钟搞定宝可梦数据合规验证 【免费下载链接】PKHeX-Plugins Plugins for PKHeX 项目地址: https://gitcode.com/gh_mirrors/pk/PKHeX-Plugins 还在为宝可梦数据的合法性验证而烦恼吗?PKHeX-Plugins项目的AutoLegalityMod插…...

从理论到实践:软件体系结构核心概念与敏捷开发融合指南

1. 软件体系结构的核心骨架 第一次接触软件架构时,我盯着满屏的UML图发懵——这些方框和箭头到底想表达什么?直到参与实际项目后才明白,架构本质上就是系统的骨架设计。就像建造房屋需要先画结构图,软件架构决定了系统由哪些"…...

为什么你需要PortProxyGUI这款Windows端口转发神器?

为什么你需要PortProxyGUI这款Windows端口转发神器? 【免费下载链接】PortProxyGUI A manager of netsh interface portproxy which is to evaluate TCP/IP port redirect on windows. 项目地址: https://gitcode.com/gh_mirrors/po/PortProxyGUI 还在为复杂…...

Python爬虫实战:手把手教你园林植物百科全自动化采集与结构化工程实践!

㊗️本期内容已收录至专栏《Python爬虫实战》,持续完善知识体系与项目实战,建议先订阅收藏,后续查阅更方便~ ㊙️本期爬虫难度指数:⭐ (基础入门篇) 🉐福利: 一次订阅后,专栏内的所有…...

胡桃工具箱完整使用指南:免费开源原神Windows桌面助手终极教程

胡桃工具箱完整使用指南:免费开源原神Windows桌面助手终极教程 【免费下载链接】Snap.Hutao 实用的开源多功能原神工具箱 🧰 / Multifunctional Open-Source Genshin Impact Toolkit 🧰 项目地址: https://gitcode.com/GitHub_Trending/sn/…...

Go语言的sync.RWMutex项目优化

Go语言中的sync.RWMutex是并发编程中常用的读写锁,它允许多个读操作同时进行,但写操作是独占的。在高并发场景下,RWMutex的性能直接影响程序的吞吐量。近年来,社区针对RWMutex进行了多项优化,显著提升了其性能表现。本…...

基于深度学习昏暗场景目标检测 极端雾天天气目标检测 YOLO与图像去雾暗通道原理算法结合应用

文章目录YOLO与图像去雾暗通道原理结合的研究综述引言2. 图像去雾与暗通道原理3. YOLO与暗通道去雾结合的动机主要代码4. YOLO与暗通道去雾结合的实现方案5. 应用实例与实验结果6. 结论与未来展望YOLO与图像去雾暗通道原理结合的研究综述 引言 YOLO的工作流程可以概括为以下几…...

手机号查询QQ号:3步找回遗忘账号的终极指南

手机号查询QQ号:3步找回遗忘账号的终极指南 【免费下载链接】phone2qq 项目地址: https://gitcode.com/gh_mirrors/ph/phone2qq 你是否曾经因为忘记QQ号而无法登录重要的工作群聊?是否因为更换手机导致QQ账号无法找回?现在&#xff0…...

HCPL-2502-500E,单通道高速光耦合器

简介今天我要向大家介绍的是 Broadcom 的光耦合器——HCPL-2502-500E。它是一款单通道、兼容 TTL/LSTTL 的高速光耦器件。该器件内部采用绝缘层隔离 LED 与集成光探测器,通过为光电二极管偏置和输出晶体管集电极提供独立连接,有效减小了基极-集电极电容&…...

N_m3u8DL-CLI-SimpleG:告别命令行!用这款免费GUI工具轻松下载M3U8视频

N_m3u8DL-CLI-SimpleG:告别命令行!用这款免费GUI工具轻松下载M3U8视频 【免费下载链接】N_m3u8DL-CLI-SimpleG N_m3u8DL-CLIs simple GUI 项目地址: https://gitcode.com/gh_mirrors/nm3/N_m3u8DL-CLI-SimpleG 还在为复杂的命令行操作而头疼吗&am…...

GLM-4.1V-9B-Base应用场景:跨境电商——商品图自动打标+多语言描述生成

GLM-4.1V-9B-Base应用场景:跨境电商——商品图自动打标多语言描述生成 1. 跨境电商的痛点与解决方案 跨境电商卖家每天需要处理大量商品图片,手动添加标签和描述不仅耗时耗力,还容易出现不一致的情况。传统方法面临三大挑战: 效…...

HCPL-2400-060E,10kV/µs高速三态输出TTL兼容逻辑门光耦合器

简介今天我要向大家介绍的是 Broadcom 的光耦合器——HCPL-2400-060E。它是一款单通道、兼容 TTL、STTL、LSTTL 和 HCMOS 逻辑的高速逻辑门光耦合器。该器件内部采用 820 nm AlGaAs 发光二极管技术,并结合了高速光探测器。其输出端为带有内置施密特触发器的三态输出…...

电力客户价值分层模型构建与K-Medoids聚类算法实战(理论详解+完整代码)

目录 一、业务背景与核心需求 二、核心理论基础 2.1 客户价值评估核心理论 2.2 K-Medoids vs K-Means(关键对比) 三、电力客户价值分层指标体系构建 3.1 指标维度与核心指标 3.2 指标预处理(正向化+标准化) 四、熵权法权重计算(完整原理+代码) 4.1 熵权法核心原理…...

避坑指南:为什么你的华硕主板WOL在Ubuntu 22.04总失效?从魔术包原理到netplan实战

华硕主板WOL失效终极排查:从魔术包原理到Ubuntu 22.04实战配置 当你在深夜急需远程访问家中服务器,却发现华硕主板搭配Ubuntu 22.04的WOL功能神秘失效时,这种挫败感足以让任何技术爱好者辗转难眠。网络唤醒(Wake-on-LAN&#xff0…...

第20篇:AI工具踩坑大全——付费陷阱、效果落差与隐私风险规避(踩坑总结)

文章目录问题现象:AI工具“真香”背后的三大暗坑排查过程:我是如何一步步掉进坑里的坑一:付费陷阱的“温水煮青蛙”坑二:效果落差的“卖家秀 vs 买家秀”坑三:隐私风险的“隐形炸弹”根本原因:为什么这些坑…...

大模型学习-python基础Day6

一.文件操作文件是存储在磁盘上的数据集合。文件可以包含各种类型的数据,如文本、图像、音频等等。文件系统通过文件名和文件路径来定位和管理文件。文件名通常包含文件的名称和和扩展名。文件路径可以是绝对路径也可以是相对路径。1.文件的分类纯文本文件&#xff…...

有限元仿真自动化:基于Python的Comsol多物理场脚本开发实践

有限元仿真自动化:基于Python的Comsol多物理场脚本开发实践 【免费下载链接】MPh Pythonic scripting interface for Comsol Multiphysics 项目地址: https://gitcode.com/gh_mirrors/mp/MPh 在科学计算与工程仿真领域,有限元分析工具的自动化控制…...

别再为包体发愁了!Unity 2019+ 开发微信小游戏的资源压缩与分包实战

Unity 2019 微信小游戏资源压缩与分包实战指南 微信小游戏4MB的初始包体限制,让不少Unity开发者头疼不已。上周团队刚上线的一款休闲游戏,就因为初始包体超标被反复打回,最后不得不连夜重构资源加载方案。本文将分享一套经过实战验证的压缩与…...

解决STM32生成Bin文件时Error: Q0122E的路径配置全攻略

1. 遇到Error: Q0122E时发生了什么? 当你正在STM32项目中使用Keil MDK进行开发,准备生成Bin文件时,突然弹出一个错误提示"Error: Q0122E: Could not open file"。这个错误通常意味着编译器无法找到fromelf.exe工具或输出文件的路径…...

终极指南:3分钟掌握Ofd2Pdf免费OFD转PDF完整教程

终极指南:3分钟掌握Ofd2Pdf免费OFD转PDF完整教程 【免费下载链接】Ofd2Pdf Convert OFD files to PDF files. 项目地址: https://gitcode.com/gh_mirrors/ofd/Ofd2Pdf 你是否经常遇到OFD格式文件无法打开、无法分享的烦恼?作为中国自主研发的电子…...