@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 的用法和作用没有任何区别。

相关推荐
飞天狗1119 小时前
零基础JavaWeb入门——第五课第二小节:九大内置对象 · 第2个:response(响应对象)
java·开发语言
许彰午9 小时前
39_Java单元测试JUnit入门
java·junit·单元测试
shushangyun_9 小时前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
JAVA96510 小时前
JAVA面试-JVM篇 03-JVM运行时数据区哪些是线程私有的哪些是共享的
java·jvm·面试
于先生吖10 小时前
教育类Java实战项目:在线错题整理平台分层架构设计与接口源码解析
java·开发语言
慧一居士10 小时前
Feign的GET请求如何传递对象参数?
java·spring cloud
ofoxcoding10 小时前
在AI API聚合平台配置DeepSeek V3.2提示词缓存实战:快速接入与成本优化指南
人工智能·spring·缓存·ai
开发小能手-roy10 小时前
Java集合框架选型指南:从ArrayList到ConcurrentSkipListMap
java·开发语言
凡人叶枫11 小时前
Effective C++ 条款41:了解隐式接口和编译期多态
java·开发语言·c++·effective c++
凡人叶枫11 小时前
Effective C++ 条款42:了解 typename 的双重意义
java·linux·服务器·c++