@MapperScan包扫描的坑

本文分享了一个在使用MyBatis通用Mapper时常见的错误:错误地导入了Spring框架中的MapperScan,而非MyBatis的MapperScan,导致运行时出现异常。正确的方式应当导入tk.mybatis.spring.annotation.MapperScan。

在使用通用mapper执行查询时,由于不太注意顺手就导了spring的包:

        import org.mybatis.spring.annotation.MapperScan;

结果就异常:tk.mybatis.mapper.provider.base.BaseSelectProvider:xxxx

找了半天才发现是包的问题,应该导mybatis的MapperScan而不是spring中的包,正确的包名:

        import tk.mybatis.spring.annotation.MapperScan;

这个报错是 Spring Boot 启动时核心的**Bean 定义加载异常**,根源是 `HouseMapper` 这个 Mapper 接口的 Bean 定义属性 `factoryBeanObjectType` 类型非法(被识别为 String 而非 Class 类型),大概率和 MyBatis/MyBatis-Plus 版本与 Spring Boot 版本不兼容、Mapper 注解使用错误或依赖冲突有关。 ### 一、核心原因分析 `factoryBeanObjectType` 是 MyBatis 整合 Spring 时用于标识 Mapper 接口类型的属性,正常情况下应该是 `Class<?>` 类型,报错显示它被解析成了 `String`,常见触发场景: 1. **MyBatis/MyBatis-Plus 版本与 Spring Boot 3.x 不兼容**:Spring Boot 3.x 基于 Spring 6.x,要求 MyBatis 至少 3.0.0+、MyBatis-Plus 至少 3.5.0+,低版本会出现类型解析兼容问题; 2. **Mapper 接口注解错误**:比如混用 `@Mapper` 和 `@Repository`、或注解配置格式错误; 3. **依赖冲突**:项目中同时引入了多个版本的 MyBatis/Spring 相关依赖; 4. **Mapper 扫描配置错误**:`@MapperScan` 注解的路径配置错误,或重复扫描。 ### 二、分步解决方案 #### 步骤 1:检查 MyBatis/MyBatis-Plus 版本(优先级最高) Spring Boot 3.5.9 属于高版本,必须确保 MyBatis/MyBatis-Plus 版本匹配: - **纯 MyBatis**:需使用 `mybatis-spring-boot-starter` 3.0.0+(推荐 3.0.3+); - **MyBatis-Plus**:需使用 `mybatis-plus-boot-starter` 3.5.3+(推荐 3.5.5+)。 修改 `pom.xml` 中的依赖版本: ```xml <!-- 若用 MyBatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.0.3</version> <!-- 关键:必须 3.0.0+ --> </dependency> <!-- 若用 MyBatis-Plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.5</version> <!-- 关键:必须 3.5.0+ --> </dependency> ``` #### 步骤 2:检查 HouseMapper 接口的注解 确保 Mapper 接口仅使用 `@Mapper` 注解(不要混用 `@Repository`),示例: ```java package com.example.qngyfwtpt.mapper; import com.example.qngyfwtpt.entity.House; import org.apache.ibatis.annotations.Mapper; // 仅保留这个注解 import java.util.List; @Mapper // 核心注解:标识为 MyBatis Mapper 接口 public interface HouseMapper { // 你的 Mapper 方法 List<House> listAll(); } ``` #### 步骤 3:检查启动类的 Mapper 扫描配置 确保启动类上的 `@MapperScan` 路径正确,且没有重复扫描: ```java package com.example.qngyfwtpt; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.example.qngyfwtpt.mapper") // 精准指向 Mapper ,不要多/少 public class QngyfwtptApplication { public static void main(String[] args) { SpringApplication.run(QngyfwtptApplication.class, args); } } ``` ⚠️ 注意:如果 Mapper 接口已经加了 `@Mapper`,`@MapperScan` 可省略;如果用了 `@MapperScan`,也可以不用给每个 Mapper 加 `@Mapper`,二选一即可,避免重复配置。 #### 步骤 4:清理依赖冲突(若版本匹配后仍报错) 1. 执行 `mvn dependency:tree` 命令,查看依赖树,检查是否有低版本的 `mybatis`/`spring-beans`/`spring-context` 依赖被引入; 2. 排除冲突依赖,示例(若有低版本 MyBatis 被间接引入): ```xml <dependency> <groupId>xxx</groupId> <!-- 其他引入 MyBatis 的依赖 --> <artifactId>xxx</artifactId> <exclusions> <exclusion> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> </exclusion> </exclusions> </dependency> ``` #### 步骤 5:清理编译目录并重新构建 1. 执行 `mvn clean` 清空 `target` 目录(删除旧的编译文件); 2. 执行 `mvn compile` 重新编译; 3. 重启 Spring Boot 应用。 ### 三、验证关键点 1. 确认 JDK 版本:Spring Boot 3.5.9 支持 JDK 17+/21,你当前用的 JDK 21.0.9 是兼容的,无需调整; 2. 确认 `application.yml/application.properties` 中 MyBatis 配置正确(比如 mapper-locations 指向 XML 文件,若用注解版可省略): ```yaml mybatis: configuration: map-underscore-to-camel-case: true # 可选,驼峰命名转换 # 若用 XML 版 Mapper,需指定路径 # mapper-locations: classpath:mapper/*.xml ``` ### 四、常见避点 - 不要同时引入 `mybatis-spring-boot-starter` 和 `mybatis-plus-boot-starter`(二选一); - 不要在 Mapper 接口上添加 `@Component`/`@Repository`(MyBatis 的 `@Mapper` 已足够,Spring 6.x 对注解类型校验更严格); - Spring Boot 3.x 不再支持 `javax.*` ,需用 `jakarta.*` 替代(但此报错和这个无关,仅提醒)。 按以上步骤调整后,`houseMapper` 的 Bean 定义就能被正确解析,启动异常即可解决。如果仍报错,可补充 `pom.xml` 中 MyBatis 相关依赖代码,我帮你精准排查版本冲突。
最新发布
12-25
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值