@Mapper注解和@MapperScan注解

这两个注解都是 MyBatis(或 MyBatis-Plus)框架里的核心注解,核心目标只有一个:让 Spring 能找到并管理你的 Mapper 接口(也就是操作数据库的 DAO 层接口),避免出现 "找不到 Mapper 实例" 的空指针异常。


1. @Mapper 注解

@Mapper加在单个 Mapper 接口上的注解,作用是告诉 Spring:"这个接口是 MyBatis 的 Mapper,需要你创建代理对象并纳入容器管理"。

用法示例

假设你有一个操作用户表的 Mapper 接口:

复制代码
// 在 Mapper 接口上直接加 @Mapper 注解
import org.apache.ibatis.annotations.Mapper;

// 标记这是一个 MyBatis Mapper 接口
@Mapper
public interface UserMapper {
    // 根据ID查用户
    User selectById(Long id);
    // 新增用户
    int insert(User user);
}

然后在 Service 层就可以直接注入使用:

复制代码
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

@Service
public class UserService {
    // Spring 能找到 UserMapper 的代理对象并注入
    @Resource
    private UserMapper userMapper;

    public User getUserById(Long id) {
        return userMapper.selectById(id);
    }
}

特点单个接口生效,需要给每个 Mapper 接口都加这个注解;


2. @MapperScan 注解

@MapperScan加在 Spring Boot 启动类上的注解,作用是告诉 Spring:"去指定的包下扫描所有 Mapper 接口,批量注册为 Spring Bean"。

它是 @Mapper 的 "批量替代方案",解决了 "每个 Mapper 都要加注解" 。

用法示例
基础用法(扫描单个包)

假设所有 Mapper 接口都放在 com.example.demo.mapper 包下:

复制代码
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// 扫描指定包下的所有 Mapper 接口
@MapperScan("com.example.demo.mapper")
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

此时,com.example.demo.mapper 包下的所有接口(比如 UserMapperOrderMapperGoodsMapper)都不需要加 @Mapper,Spring 会自动扫描并注册。

进阶用法(扫描多个包)

如果 Mapper 分散在多个包下,可以用数组形式指定:

复制代码
// 扫描多个包下的 Mapper
@MapperScan({"com.example.demo.mapper.user", "com.example.demo.mapper.order"})
@SpringBootApplication
public class DemoApplication {
    // ...
}
进阶用法(指定接口父类 / 注解)

如果想更精准地扫描(比如只扫描标记了自定义注解的 Mapper),可以用 annotationClass 参数:

复制代码
// 只扫描带有 @MyCustomMapper 注解的接口
@MapperScan(basePackages = "com.example.demo.mapper", annotationClass = MyCustomMapper.class)
@SpringBootApplication
public class DemoApplication {
    // ...
}

特点包级别批量生效,一次配置,整个包下的 Mapper 都被管理;


两者核心对比表

注解 加在何处 作用范围 适用场景 核心优点 核心缺点
@Mapper 单个 Mapper 接口上 单个接口 小项目(Mapper 少) 直观,新手易上手 重复加注解,繁琐
@MapperScan Spring Boot 启动类上 指定包下所有接口 中大型项目(Mapper 多) 批量配置,简洁高效 路径写错会扫描失败

常见问题 & 注意事项

  1. 两个注解能不能同时用? 可以,但没必要。如果用了 @MapperScan,Mappe 接口上的 @Mapper 注解会被忽略(相当于 "批量通知已经覆盖了单个通知")。

  2. 扫描不到 Mapper 怎么办?

    • 检查 @MapperScan 的包路径是否正确(比如少写了一层包名);
    • 检查 Mapper 接口是否是接口(不是类);
    • 检查启动类是否在 Mapper 包的上层(Spring Boot 默认扫描启动类所在包及子包,@MapperScan 可以突破这个限制)。
  3. MyBatis-Plus 中用法一样吗? 完全一样。MyBatis-Plus 兼容 MyBatis 的注解,@Mapper/@MapperScan 的用法和作用没有任何区别。

相关推荐
NE_STOP6 小时前
MyBatis-配置文件解读及MyBatis为何不用编写Mapper接口的实现类
java
后端AI实验室11 小时前
用AI写代码,我差点把漏洞发上线:血泪总结的10个教训
java·ai
程序员清风13 小时前
小红书二面:Spring Boot的单例模式是如何实现的?
java·后端·面试
belhomme13 小时前
(面试题)Redis实现 IP 维度滑动窗口限流实践
java·面试
Be_Better13 小时前
学会与虚拟机对话---ASM
java
开源之眼15 小时前
《github star 加星 Taimili.com 艾米莉 》为什么Java里面,Service 层不直接返回 Result 对象?
java·后端·github
Maori31616 小时前
放弃 SDKMAN!在 Garuda Linux + Fish 环境下的优雅 Java 管理指南
java
用户9083246027317 小时前
Spring AI 1.1.2 + Neo4j:用知识图谱增强 RAG 检索(上篇:图谱构建)
java·spring boot
小王和八蛋17 小时前
DecimalFormat 与 BigDecimal
java·后端