Mapper XML 文件纳入 classpath 的解决方案

文章目录

一、背景与问题描述

在使用 MyBatis 进行开发时,一般会将 Mapper 接口(.java) 存放于 src/main/java,而将对应的 Mapper XML(.xml) 存放于 src/main/resources 下,以便在 Maven 打包时,.xml 文件能够自动复制到 target/classes 目录,最终纳入 classpath 中。

如果因项目结构或其他原因,需要将 Mapper XMLMapper 接口 放置在同一目录(即 src/main/java/com/xxx/dao),就会遇到下列问题:

默认情况下,Maven 只编译 src/main/java 中的 .java 文件,并不会把 .xml 文件复制到 target/classes。结果是 MyBatis 在运行时无法在 classpath 中找到对应的 XML 映射文件,导致出现 "Invalid bound statement (not found)" 或 "Could not find mapper file..." 等错误。

为解决此问题,需要修改 Maven 的资源复制配置,让 src/main/java 中的 .xml 文件也被视作资源文件,编译打包时一并放入 target/classes


二、原理与思路

  1. Maven 资源(resources)机制
    • 默认情况下,Maven 会将 src/main/resources 目录下的所有文件拷贝到 target/classes,因此在运行或打包(jar/war)时,这些文件会处于 classpath 内。
    • src/main/java 目录下通常只放置 .java 文件进行编译,.xml.properties 等非 .java 文件不会自动复制到 target/classes
  2. 将特定目录或文件纳入资源
    • Maven 提供 <resources> 配置,让我们可以对任意目录 执行资源复制,也可以通过 <includes> / <excludes> 来筛选文件类型。
    • 只要在 <resources> 中添加一个 <resource> 块,指定 directory=src/main/javainclude=**/*.xml,就能让 .xml 文件也被复制到 target/classes
  3. MyBatis 加载 Mapper XML
    • MyBatis 需要在 classpath 中找到 Mapper XML 文件,无论是通过 mapperLocations=classpath*:**/*.xml 方式,还是在 mybatis-config.xml<mapper resource="..."> 方式,都依赖文件实际存在于 classpath
    • 因此,只有当 Maven 把 .xml 复制进 target/classes 后,MyBatis 才能在 classpath 中正确读取这些文件。

三、具体配置示例

在你的项目的 pom.xml 中,找到 <build> 节点,添加(或修改)如下 <resources> 配置:

xml 复制代码
<build>
    <!-- 项目打包名称,可不关注 -->
    <finalName>intelligenceCommand</finalName>
    
    <resources>
        <!-- 默认资源目录,保留不动。如果你没有此段,可自行添加 -->
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*</include>
            </includes>
        </resource>

        <!-- 额外添加,将 src/main/java 下的所有 .xml 文件也视为资源 -->
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>

配置解析

  1. <directory>src/main/java</directory>
    指定要扫描的目录为 src/main/java
  2. <includes><include>**/*.xml</include></includes>
    仅复制此目录下所有 .xml 文件(递归子目录),其余 .java 文件不会被当作资源。
  3. src/main/resources 配置还保留,方便项目其他配置文件(如 application.propertiesmybatis-config.xml 等)也能被复制到 target/classes

当你执行 mvn clean package(或其他构建命令)后,Maven 就会:

  • 编译 src/main/java 下的 .java 文件生成 .class 放到 target/classes
  • 同时src/main/java 下的 .xml 文件复制到 target/classes

这样在运行阶段 ,所有 .xml 文件便存在于 classpath 下,MyBatis 即可加载它们。


四、验证与注意事项

  1. 查看编译输出

    • 在执行 mvn clean package 后,进入 target/classes/com/xxx/dao/ 目录,确认能看到相应的 .xml 文件。如果没有,说明资源配置未生效或写法有误。
  2. MyBatis 中的 Mapper 配置

    • 需要在 mybatis-config.xml或者 SqlSessionFactoryBean 的 mapperLocations中指定正确的扫描路径:

      xml 复制代码
      <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
          <property name="dataSource" ref="personDataSource" />
          <property name="mapperLocations" value="classpath*:com/zxz/intelligenceCommand/dao/*.xml" />
          ...
      </bean>

      或者在 mybatis-config.xml 中写:

      xml 复制代码
      <configuration>
          <mappers>
              <mapper resource="com/zxz/intelligenceCommand/dao/RoleDao.xml"/>
              <mapper resource="com/zxz/intelligenceCommand/dao/UserDao.xml"/>
              ...
          </mappers>
      </configuration>
    • 只要你保证编译后路径下有 RoleDao.xml 等文件,MyBatis 就能找到。

  3. 避免与默认资源重复或冲突

    • 如果你在 src/main/resources 下也有同名 .xml,可能会产生冲突或覆盖(除非你刻意这么做)。一般不建议同名重叠。
  4. 项目结构最佳实践

    • 虽然通过这种方式可以将 .xml 文件和 .java 文件放在同一目录,但更常见或更推荐的做法是把 Mapper XML 放进 src/main/resources/mapper 之类的专门目录,使结构更清晰。

五、总结

目标 :在 src/main/java.java 同一目录下的 .xml 文件也能编译进 classpath
方法 :在 pom.xml<build><resources> 中,额外增加一个 <resource> 配置项,指向 src/main/java 并用 <include>**/*.xml</include>,即可将对应的 XML 文件复制到 target/classes

通过以上操作,可确保 MyBatis 在运行时正常加载这些 Mapper XML 文件,避免由于找不到映射而引发的 "Invalid bound statement (not found)" 等错误。

相关推荐
文盲青年7 小时前
springboot适配mybatis+guassdb与Mysql兼容性问题处理
spring boot·mysql·mybatis
綦枫Maple11 小时前
Spring Boot(4)使用 IDEA 搭建 Spring Boot+MyBatis 项目全流程实战
spring boot·intellij-idea·mybatis
123yhy传奇16 小时前
【学习总结|DAY028】后端Web实战(部门管理)
java·学习·mysql·log4j·maven·mybatis·web
计算机毕设定制辅导-无忧学长1 天前
MyBatis 配置文件全解析
mybatis
qxlxi1 天前
【mybatis】Mybatis整体架构解析
架构·mybatis
天之涯上上2 天前
JAVA开发中 MyBatis XML 映射文件 的作用
xml·java·mybatis
knighthood20012 天前
xml格式化(1):使用python的xml库实现自闭合标签
android·xml·python
沐霜枫叶2 天前
Flink CDC 自定义函数处理 SQLServer XML类型数据 映射 doris json字段方案
xml·sqlserver·flink·doris·cdc
风月歌2 天前
基于Web的足球青训俱乐部管理后台系统的设计与开发源码(springboot+mysql+vue)
java·前端·spring boot·后端·mysql·mybatis·源码