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

Spring Boot + MyBatis服务启动流程,新增代码跑通流程,映射规则,常见问题定位

一、服务启动流程零代码仅需配置文件和依赖。顺序固定由框架保证。一旦某个步骤失败如 XML 解析错误整个启动失败。二、新增代码跑通流程全手动需熟悉 MyBatis 映射规则、Spring 注解。编译时和运行时都可能出错如 XML 重复 id、SQL 语法错误、依赖注入循环等。结合启动流程新增代码必须符合启动流程的预期如 XML 位置必须在 mapperLocations 扫描路径内。三、 MyBatis 映射规则统一使用 XML 管理复杂映射尤其是动态 SQL 和关联查询注解适合简单查询。避免注解和 XML 混用除非明确分开 id。为每个表/模块独立一个 Mapper XML 片段 id 在同一文件内唯一。启用下划线转驼峰减少冗余的 resultMap。使用 Param 明确命名多参数提高可读性且避免参数顺序问题。开启 MyBatis 日志logging.level.com.example.mapperDEBUG快速定位映射错误。【基础映射resultType 与 resultMap】方式一resultType查询结果列名与 Java 属性名一致或通过 autoMapping 能匹配自动映射列名 user_name → 属性 userName需开启下划线转驼峰方式二resultMap列名与属性名不一致、需要复杂关联映射、类型转换控制显式定义 可指定 id、result、association、collection!-- resultType 自动映射 --selectidselectUserresultTypecom.example.Userselect user_id, user_name from user/select!-- resultMap 显式映射 --resultMapiduserMaptypeUseridcolumnuser_idpropertyuserId/resultcolumnuser_namepropertyuserName//resultMapselectidselectUserMapresultMapuserMapselect user_id, user_name from user/select【属性映射细节】下划线转驼峰自动映射全局配置启用后user_name → userName。mybatis:configuration:map-underscore-to-camel-case:true类型处理器TypeHandler 用法【参数映射】参数映射 指的是将 Java 方法中的实际参数值安全、正确地传递给 SQL 语句中占位符 #{…} 的过程。这是 MyBatis 执行 SQL 前的重要环节直接关系到 SQL 能否正确执行以及是否安全防 SQL 注入。在 Spring Boot MyBatis 注解/XML 混合开发中大多数情况下MyBatis 通过反射或 Param 注解能自动推断参数类型不需要显式写 parameterType仅在遇到参数为 null 导致异常或使用旧版 MyBatis 时才显式指定。方式一单个参数 xml的SQL语句中直接使用 #{任意名称}基础类型示例selectidgetUserByIdparameterTypelongresultTypeUserselect * from user where id #{id}/select对象示例自动读取对象的属性insertidinsertUserparameterTypeUserinsert into user(name, age) values(#{name}, #{age})/insertMap示例selectidgetUserparameterTypemapresultTypeUserselect * from user where id #{id}/select方式二 多个参数必须使用 Param。接口中通过 Param 重命名入参的名称xml的sql语句直接使用 #{属性名}UsergetUser(Param(uid)Longid,Param(name)Stringusername);selectidgetUserresultTypeUserselect * from user where id #{uid} and name #{name}/select【动态SQL】场景一 动态生成WHERE子句自动处理 AND 前缀去除多余的 AND/ORwhereiftestname ! null and name ! AND name LIKE CONCAT(%, #{name}, %)/ififtestage ! nullAND age #{age}/if/where场景二 动态生成 SET 子句自动去除多余逗号用于更新setiftestname ! nullname #{name},/ififtestage ! nullage #{age},/if/set场景三 多条件分支等价于 switch-case-defaultselectidselectUsersOrderByresultTypeUserSELECT * FROM userchoosewhentestorderField nameORDER BY name/whenwhentestorderField ageORDER BY age/whenotherwiseORDER BY id/otherwise/choose/select场景四 遍历集合foreachcollectionlistitemidopen(separator,close)#{id}/foreach场景五 绑定变量避免在 Java 代码中手动拼接selectidsearchUsersresultTypeUserbindnamepatternvalue% keyword %/SELECT * FROM user WHERE name LIKE #{pattern}/select场景六 自定义前缀、后缀、覆盖规则 自定义前缀、后缀、覆盖规则【关联映射】针对 SQL 语句执行结果的映射MyBatis 中的 一对一、一对多、多对多通常拆解为两个一对多 映射其本质就是 将 SQL 查询返回的扁平结果集多表连接后的表状数据转换为 Java 对象图。关联映射的输入SQL 语句执行后返回的 ResultSet扁平表结构。关联映射的输出具有嵌套关系的 Java 对象图。实现方式在 中定义 或 子标签指定子对象的属性、列映射以及如何区分不同行通过 标签。优势避免手动循环组装对象MyBatis 自动完成。场景一一对一classUser{privateLongid;privateRolerole;// 嵌套对象}resultMapiduserWithRoleMaptypeUseridcolumnidpropertyid/resultcolumnnamepropertyname/associationpropertyrolejavaTypeRoleidcolumnrole_idpropertyid/resultcolumnrole_namepropertyname//association/resultMapselectidgetUserWithRoleresultMapuserWithRoleMapSELECT u.id, u.name, r.id as role_id, r.name as role_name FROM user u LEFT JOIN role r ON u.role_id r.id WHERE u.id #{id}/select场景二一对多classUser{privateLongid;privateListOrderorders;}resultMapiduserWithOrdersMaptypeUseridcolumnidpropertyid/collectionpropertyordersofTypeOrderidcolumnorder_idpropertyid/resultcolumnorder_amountpropertyamount//collection/resultMapselectidgetUserWithOrdersresultMapuserWithOrdersMapSELECT u.id, o.id as order_id, o.amount as order_amount FROM user u LEFT JOIN orders o ON u.id o.user_id WHERE u.id #{id}/select场景三多对多 拆分为两个一对多或使用中间表关联。四、常见问题定位【报错一】[2026-05-22T06:52:08.12308:00 WARN 18792 — [study3] [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘authController’: Unsatisfied dependency expressed through field ‘userService’: Error creating bean with name ‘userService’: Unsatisfied dependency expressed through field ‘userMapper’: Error creating bean with name ‘userMapper’ defined in file [D:\demo2026\study3\study3\target\classes\com\example\study3\mapper\UserMapper.class]: Cannot resolve reference to bean ‘sqlSessionTemplate’ while setting bean property ‘sqlSessionTemplate’问题定位查看 Spring Boot 自动配置报告在 application.properties 中添加debugtrue重启应用控制台查看日志a. 关键字 DataSourceAutoConfiguration出现在 Negative matches 中b. 关键字 MyBatisAutoConfiguration出现在Positive matches 中解释sqlSessionTemplate Bean ——自动配置类匹配了但在实际创建 SqlSessionTemplate Bean 的过程中发生了异常导致该 Bean 最终没有被注册到容器中。日志说明类路径中存在 MyBatis 核心类存在唯一的 DataSource Bean没有自定义的 SqlSessionFactory 和 SqlSessionTemplate理论上 Spring 会自动创建 sqlSessionTemplate Bean但实际却失败了这说明 Bean 的实例化过程中抛出了异常可能是创建 SqlSessionFactory 时失败导致 sqlSessionTemplate 无法创建。c. 关键字 ‘sqlSessionFactory’根本原因TaskCheckResultMapper.xml 这个 MyBatis 映射文件解析失败了导致 sqlSessionFactory 无法创建进而引发 sqlSessionTemplate Bean 缺失最终导致 UserMapper 创建失败d. 关键字 Failed to parse mapping resource异常Mapped Statements collection already contains key com.example.study3.mapper.TaskCheckResultMapper.update解释MyBatis 中已经存在一个 id 为 update 的映射语句当尝试再次添加时发生冲突。这通常是因为 同一个 Mapper 接口中注解和 XML 定义了相同 id 的 SQL 操作。异常Error parsing Mapper XML. The XML location is ‘file [xxx.xml]’. Cause: java.lang.IllegalArgumentException: XML fragments parsed from previous mappers already contains key com.解释xml中 被定义了两次导致 MyBatis 解析时出现重复键冲突。通过注解定义方式MapperpublicinterfaceTaskCheckResultMapper{Insert(INSERT INTO task_check_results (execution_id, checker_user_id, check_time, score, level, feedback, auto_checked, details_json) VALUES (#{executionId}, #{checkerUserId}, #{checkTime}, #{score}, #{level}, #{feedback}, #{autoChecked}, #{detailsJson}))Options(useGeneratedKeystrue,keyPropertycheckId)intinsert(TaskCheckResultresult);Select(SELECT * FROM task_check_results WHERE execution_id #{executionId})TaskCheckResultselectByExecutionId(LongexecutionId);Update(UPDATE task_check_results SET score #{score}, level #{level}, feedback #{feedback}, details_json #{detailsJson} WHERE check_id #{checkId})intupdate(TaskCheckResultresult);Delete(DELETE FROM task_check_results WHERE execution_id #{executionId})intdeleteByExecutionId(LongexecutionId);}xml方式?xml version1.0 encodingUTF-8?!DOCTYPEmapperPUBLIC-//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtdmappernamespacecom.example.study3.mapper.TaskCheckResultMapperresultMapidBaseResultMaptypecom.example.study3.entity.TaskCheckResultidcolumncheck_idpropertycheckId/resultcolumnexecution_idpropertyexecutionId/resultcolumnchecker_user_idpropertycheckerUserId/resultcolumncheck_timepropertycheckTime/resultcolumnscorepropertyscore/resultcolumnlevelpropertylevel/resultcolumnfeedbackpropertyfeedback/resultcolumnauto_checkedpropertyautoChecked/resultcolumndetails_jsonpropertydetailsJson//resultMapinsertidinsertuseGeneratedKeystruekeyPropertycheckIdINSERT INTO task_check_results (execution_id, checker_user_id, check_time, score, level, feedback, auto_checked, details_json) VALUES (#{executionId}, #{checkerUserId}, #{checkTime}, #{score}, #{level}, #{feedback}, #{autoChecked}, #{detailsJson})/insertselectidselectByExecutionIdresultMapBaseResultMapSELECT * FROM task_check_results WHERE execution_id #{executionId}/selectupdateidupdateUPDATE task_check_results SET score #{score}, level #{level}, feedback #{feedback}, details_json #{detailsJson} WHERE check_id #{checkId}/updatedeleteiddeleteByExecutionIdDELETE FROM task_check_results WHERE execution_id #{executionId}/delete/mapper
http://www.zskr.cn/news/1360884.html

相关文章:

  • 用Delphi 7打造动物农场小游戏:一场编程与数据结构的趣味之旅
  • 嵌入式-不同数据的存储区域 5.22
  • Python学习教程(六)数据结构List(列表)
  • 戴森球计划终极蓝图仓库:5步快速构建完美自动化工厂的完整指南
  • Windows平台APK安装器:轻松在电脑上安装安卓应用
  • 为什么你的财务月报总是做不完?如何用对方法让财务月报自动生成?
  • vue3 大屏列表轮播,使用transition-group
  • 昇腾CANN ops-transformer MoE:专家混合路由的 NPU 融合优化实战
  • 136、运动控制中的同步机制:时间戳与触发
  • 如何用代码缺陷率评估代码质量与团队产出效率——从单一指标到量化管理体系的升级路径
  • 137、运动控制中的故障诊断与安全机制
  • 【限时公开】我们压测了23个开源AI Agent框架,仅2个支持亚秒级SQL生成+自动schema纠错(测试报告PDF已备)
  • 昇腾CANN manifest:仓库清单与版本管理实战
  • 苏州二手注塑机哪家好?本地优质厂家与选购要点推荐 - GrowthUME
  • 正则表达式不再头疼:用 AI 生成并验证复杂的字符串匹配规则
  • 测试数据造假神器:利用 LLM 批量生成符合业务逻辑的连贯 Mock 数据
  • 【Claude+IDE深度协同】:VS Code与JetBrains插件配置终极手册(含私有模型微调接口)
  • 【信息系统项目管理师论文押题】论信息系统项目的不确定性绩效域
  • 【光学】偏振光线追迹Matlab仿真
  • 用weelinking大模型聚合平台深度测评Codex VS Claude Code:谁才是真正的AI编程之王?
  • 2026专业GEO优化服务商TOP推荐(11大全覆盖) - GrowthUME
  • CBCX:平台稳定性与用户体验的全面观察
  • 企业级RAG落地需要考虑的七个优化指标
  • 从零打造 AI 小说创作平台(四):项目与章节管理
  • UE5官方文档(第一人称射击游戏教程)解读 第七章
  • agent-skills 完整使用教程(2026最新版)
  • TCP可靠传输机制——“不丢包“背后的技术秘密
  • MLX框架深度优化指南:解锁苹果芯片的机器学习潜能
  • 03华夏之光永存:28nm工艺发展趋势|成熟制程长期黄金期+国产自主超车主线
  • 合肥租厂房该找谁 - GrowthUME