记一次粗心导致的错误:new PathMatchingResourcePatternResolver().getResource(“classpath:mapper/db2/*.xml“)

本文介绍了一个关于MyBatis框架中找不到XML映射文件的问题及其解决办法。错误原因是使用了PathMatchingResourcePatternResolver的getResource方法而不是getResources方法。getResource不支持通配符,而getResources支持。

错误日志如下:

Caused by: java.io.FileNotFoundException: class path resource [mapper/db2/*.xml] cannot be opened because it does not exist
    at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:180) ~[spring-core-5.2.12.RELEASE.jar:5.2.12.RELEASE]
    at org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:591) ~[mybatis-spring-2.0.3.jar:2.0.3]
    ... 74 common frames omitted

Java错误段的代码:

@Bean(name = "db2SqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("db2DataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResource("classpath:mapper/db2/*.xml"));
  
### MyBatis 中 `mapper-locations` 配置最佳实践与常见问题分析 #### 1. **`classpath:` 和 `classpath*:` 的区别** 在 MyBatis 中,`mybatis.mapper-locations` 属性用于指定 Mapper XML 文件的位置。其中,`classpath:` 和 `classpath*:` 是两种不同的路径匹配方式。 - **`classpath:`** 表示仅在当前项目的类路径下查找资源文件。它只会扫描单个类加载器的路径,并不会深入到依赖的 JAR 包中去查找资源文件[^1]。 - **`classpath*:`** 则表示在整个类路径及其所有依赖包中查找资源文件。它可以跨越多个类加载器以及 JAR 包中的资源文件进行扫描[^2]。 因此,在配置时需根据实际情况选择合适的路径匹配方式。如果项目结构简单且不涉及第三方依赖,则可使用 `classpath:`;但如果需要支持模块化开发或跨 JAR 扫描,则推荐使用 `classpath*:`。 --- #### 2. **最佳实践** ##### (1)清晰定义路径模式 为了提高效率和减少不必要的扫描时间,建议明确指定 Mapper XML 文件所在的目录及名称模式。例如: ```properties # 只会扫描当前类路径下的 /sql/ 目录 mybatis.mapper-locations=classpath:/sql/*.xml # 扫描整个类路径及其依赖包中的 sql 目录 mybatis.mapper-locations=classpath*:sql/*.xml # 更具体的例子:只加载 mapper 下的所有 XML 映射文件 mybatis.mapper-locations=classpath*:mapper/*.xml ``` 通过以上配置可以有效缩小搜索范围,提升应用启动速度的同时也降低了潜在错误的风险[^3]。 ##### (2)避免重复加载 当使用 `classpath*:` 时需要注意可能存在的重复加载问题。假如同一个 Mapper XML 文件存在于多个地方(比如源码目录和服务端部署后的 JAR 文件内),那么可能会导致两次甚至多次加载同一份映射文件,从而引发运行期异常。为了避免这种情况的发生,应该确保每个 Mapper XML 文件都有唯一的存在位置。 ##### (3)结合 Spring Boot 自动配置特性 如果是基于 Spring Boot 开发的应用程序,默认情况下已经集成了 MyBatis 支持。此时无需手动编写复杂的 XML 或者 Java Config 来注册 Mappers ,只需按照约定放置好对应的 Mapper 接口和 XML 文件即可自动完成绑定工作 。默认规则如下: - Mapper 接口通常位于 `com.example.demo.mapper` 类似的包名空间; - 对应的 XML 文件应当存放在 resources/mapper/ 目录下并与接口同名 (如 UserMapper.java -> UserMapper.xml)[^3]。 在这种场景下,只需要简单的声明一下 base package 即可让框架自行发现并管理所有的 Mapper 组件: ```yaml mybatis: mapper-locations: classpath*:mapper/**/*.xml type-aliases-package: com.example.domain.model ``` 这里的 `**/*` 符号代表递归子目录的意思,即不仅限于顶层 mapper 文件夹还会向下继续探索更深一层级里的 XML 文档。 --- #### 3. **常见问题及解决方案** | 常见问题 | 描述 | 解决方案 | |----------|------|---------| | **无法找到 Mapper XML 文件** | 如果报错提示找不到某张表的操作方法对应的关系描述文档,则可能是由于未正确定位到其物理存储地点所致。 | 检查 `mybatis.mapper-locations` 是否涵盖了目标文件所在的实际路径; 同时确认所使用的通配符(`classapth:` vs `classpath*`)是否恰当。 | | **SQL 查询失败** | 出现类似 No statement found with id="..." 错误信息表明虽然找到了 XML 文件但是未能成功解析里面的 Statement 定义项。 | 确认 XML 文件语法无误, 并且 namespace 正确指向关联的 Mapper Interface ;另外还要留意大小写敏感度问题因为在 Linux 系统上文件系统区分字母大小写的缘故可能导致意外的结果。 | | **性能下降** | 当项目规模较大时 , 不加限制的大面积扫描会造成额外开销进而拖慢整体表现水平。 | 缩小扫描区域至最小必要限度之内并通过日志观察实际执行情况以便及时调整优化策略 | --- ### 示例代码展示 下面给出一段完整的 Spring Boot 配合 MyBatis 使用的例子来说明如何正确设置 `mapper-locations` 参数 : ```java @SpringBootApplication @MapperScan(basePackages = {"com.mycompany.app.mappers"}) public class Application { public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } } // application.yml configuration file content as below : mybatis: mapper-locations: classpath*:mappings/**/*Mapper.xml type-aliases-package: com.mycompany.app.models // Example of one such mapping definition inside mappings/user/UserMapper.xml : <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.mycompany.app.mappers.UserMapper"> <!-- Select all users --> <select id="selectAllUsers" resultType="User"> SELECT * FROM USER_TABLE ORDER BY ID ASC LIMIT #{limit}; </select> </mapper> ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

睡竹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值