这两个注解都是 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 包下的所有接口(比如 UserMapper、OrderMapper、GoodsMapper)都不需要加 @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 多) | 批量配置,简洁高效 | 路径写错会扫描失败 |
常见问题 & 注意事项
-
两个注解能不能同时用? 可以,但没必要。如果用了
@MapperScan,Mappe 接口上的@Mapper注解会被忽略(相当于 "批量通知已经覆盖了单个通知")。 -
扫描不到 Mapper 怎么办?
- 检查
@MapperScan的包路径是否正确(比如少写了一层包名); - 检查 Mapper 接口是否是接口(不是类);
- 检查启动类是否在 Mapper 包的上层(Spring Boot 默认扫描启动类所在包及子包,
@MapperScan可以突破这个限制)。
- 检查
-
MyBatis-Plus 中用法一样吗? 完全一样。MyBatis-Plus 兼容 MyBatis 的注解,
@Mapper/@MapperScan的用法和作用没有任何区别。