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

【MyBatis新手避坑】详解 `Could not find resource ...Mapper.xml` 错误

文章目录

      • 一、 问题发现:当满屏红色指向一个“文件找不到”的错误
      • 二、 为啥?深入理解 Maven/Gradle 的构建约定
      • 三、 咋办?两种解决方案(强烈推荐第一种)
        • 方案一:【最佳实践】将 Mapper.xml 文件移至 `resources` 目录
        • 方案二:【备用方案】修改 `pom.xml` 配置文件
      • 四、 总结

如果你是一位正在学习 MyBatis 的 Java 开发者,那么你很可能在某个深夜,满怀期待地运行第一个测试时,被一盆红色的 ExceptionInInitializerError 冷水浇得透心凉。别灰心,这几乎是每个 MyBatis 新手的“成年礼”。今天,我们就来彻底解剖这个经典的错误,让你不仅知道“咋办”,更明白“为啥”。

一、 问题发现:当满屏红色指向一个“文件找不到”的错误

让我们先回顾一下案发现场。你可能像我一样,精心编写了 StudentDao 接口、StudentMapper.xml 映射文件,以及一个用于获取 SqlSessionMyBatisUtils 工具类。然后,当你运行 StudentDaoTest 时,控制台却无情地打印出如下错误:

Exception in thread "main" java.lang.ExceptionInInitializerErrorat com.github.xxx.dao.StudentDaoTest.main(StudentDaoTest.java:16)
Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error building SqlSession.
### The error may exist in com/github/xxx/dao/StudentMapper.xml
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/github/xxx/dao/StudentMapper.xml...
Caused by: java.io.IOException: Could not find resource com/github/xxx/dao/StudentMapper.xml...

作为“侦探”,我们应该学会从错误堆栈(Stack Trace)中寻找线索。拨开层层上报的异常迷雾,我们最终会定位到最根本的原因(Root Cause):

java.io.IOException: Could not find resource com/github/xxx/dao/StudentMapper.xml

这句话的潜台词非常直白:“嘿,我(MyBatis)找不到你让我加载的 StudentMapper.xml 这个文件!

二、 为啥?深入理解 Maven/Gradle 的构建约定

要理解为什么会找不到,我们必须先了解 Java 项目构建工具(如 Maven 或 Gradle)的基本工作原理,这被称为“约定优于配置”(Convention over Configuration)。

在一个标准的 Maven 项目中,目录结构有着明确的约定:

  • src/main/java存放 Java 源代码(.java 文件)。构建时,这个目录下的 .java 文件会被编译成 .class 文件,并输出到 target/classes 目录。
  • src/main/resources存放所有资源文件(非 .java 文件)。例如 .xml, .properties 等。构建时,这个目录下的所有文件和目录结构会被原封不动地复制target/classes 目录。

那么,问题的根源就浮出水面了:

我们通常习惯于将 StudentMapper.xml 和它的接口 StudentDao.java 放在同一个包下,也就是 src/main/java/com/github/xxx/dao/。然而,根据 Maven 的默认约定,它只会编译 java 目录下的 .java 文件,而会忽略掉所有的 .xml 文件

最终导致的结果是,项目编译打包后,你的 target/classes 目录中只包含了 StudentDao.class,而 StudentMapper.xml 却“人间蒸发”了。当程序运行时,MyBatis 在 Classpath(也就是 target/classes)里自然找不到这个至关重要的 XML 文件,于是毫不犹豫地抛出了 IOException

三、 咋办?两种解决方案(强烈推荐第一种)

既然找到了病因,对症下药就变得非常简单了。

方案一:【最佳实践】将 Mapper.xml 文件移至 resources 目录

这是最符合 Maven 规范,也是业界通用的标准做法。它能确保你的项目结构清晰,职责分明。

  1. 定位 resources 目录:在你的项目结构中,找到 src/main/resources

  2. 创建镜像目录:在 resources 目录下,手动创建与你的 Dao 接口包名完全相同的目录结构。

    • 例如,如果你的 Dao 接口在 com.github.xxx.dao,那么就在 resources 下创建 com/github/xxx/dao
  3. 移动文件:将 StudentMapper.xml 文件从 src/main/java/... 目录剪切并粘贴到新创建的 src/main/resources/com/github/xxx/dao/ 目录下。

最终,你的项目结构会是这样,清爽又规范:

src
├── main
│   ├── java
│   │   └── com/github/xxx/dao
│   │       └── StudentDao.java          # 接口留在这里
│   │
│   └── resources
│       ├── com/github/xxx/dao
│       │   └── StudentMapper.xml      # XML文件移到这里
│       │
│       └── mybatis-config.xml         # 其他资源文件
│
└── test
  1. 重新运行:现在,重新运行你的测试代码。Maven 会将 resources 下的所有内容 faithfully 复制到 target/classes,MyBatis 将顺利找到它的映射文件,错误也就随之消失。
方案二:【备用方案】修改 pom.xml 配置文件

如果你有强烈的个人偏好,坚持要将 .java.xml 文件放在一起,也不是不可以。你需要通过修改 pom.xml 文件来覆盖 Maven 的默认行为

  1. 打开项目根目录下的 pom.xml 文件。
  2. <build> 标签内,添加如下 <resources> 配置。这相当于告诉 Maven:“除了 resources 目录,也请把 java 目录下的 .xml 文件当作资源文件处理。”
<build><resources><!-- 处理 src/main/java 目录下的 XML 文件 --><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes><filtering>false</filtering></resource><!-- 确保 src/main/resources 的默认行为不受影响 --><resource><directory>src/main/resources</directory><includes><include>**/*.xml</include><include>**/*.properties</include></includes><filtering>true</filtering></resource></resources>
</build>
  1. 保存 pom.xml 文件,等待 IDE 刷新 Maven 配置后,再次运行即可。

虽然这种方法也能解决问题,但我个人不太推荐。因为它破坏了“约定优于配置”的原则,可能会让其他接手你项目的开发者感到困惑。

四、 总结

编程中的许多错误,看似是代码逻辑问题,实则是对工具链和底层原理理解不够深入。Could not find resource 这个错误就是最好的例子。

  • 病因:Maven/Gradle 默认不打包 src/main/java 目录下的资源文件。
  • 药方:遵循“约定优于配置”的原则,将资源文件(如 .xml)放置在 src/main/resources 目录下,并保持与 Java 包结构一致的目录结构。

希望这篇博客能帮助你彻底告别这个“新手村”的拦路虎。如果你觉得有帮助,欢迎点赞、收藏和分享!下次遇到问题,记得先从“为什么”开始思考,你会发现编程的世界会因此变得更加清晰。Happy Coding!

http://www.lryc.cn/news/611932.html

相关文章:

  • 从博客到播客:文本转音频的全流程技术点
  • C++ - 仿 RabbitMQ 实现消息队列--网络通信协议设计
  • DOM的XML命名空间革命:从混乱到有序的蜕变
  • IP与MAC地址的区别解析
  • OpenAI重磅推出开源模型!gpt-oss-120b与20b全面解析
  • OpenAI/gpt-oss开源模型部署与使用全指南
  • OpenAI 开源GPT OSS系列模型
  • 小实验--震动点灯
  • GPT-OSS 与 Ollama 完整安装使用教程
  • 【JavaEE】(8) 网络原理 HTTP/HTTPS
  • NWinfo(硬件信息检测工具)v1.4.20绿色免费版,U盘随走随检,结果即刻导出
  • DM数据库的安全版本SYSDBA无法修改其他用户密码?
  • 基于串口实现可扩展的硬件函数 RPC 框架(附完整 Verilog 源码)
  • HarmonyOS应用开发环境搭建以及快速入门介绍
  • 【大模型系列】gpt-oss系列模型初探
  • 前端UI组件库
  • WMS及UI渲染底层原理学习
  • ROG 掌机 X:便携游戏新宠,开启微观生存冒险
  • JAVA 程序员cursor 和idea 结合编程
  • OpenAI最新开源:GPT-OSS原理与实践
  • 需求如何映射到开发计划中
  • 江协科技STM32 15-1 FLASH闪存
  • Unity模型显示在UI上
  • IDS知识点
  • 在ubuntu上使用jenkins部署.net8程序
  • 【网络安全】入侵检测系统 Suricata 概述 | IDS
  • DHCP 服务器与DNS服务器
  • 如何将照片从POCO手机传输到Mac电脑
  • Linux基础命令的生产常用命令及其示例简单解释
  • Mac 洪泛攻击笔记总结补充