目录
[1. @Mapper(MyBatis 注解)](#1. @Mapper(MyBatis 注解))
[2. @Repository(Spring 注解)](#2. @Repository(Spring 注解))
[3. 二者在 MyBatis 项目中的协作关系](#3. 二者在 MyBatis 项目中的协作关系)
[场景 1:使用 @MapperScan(推荐)](#场景 1:使用 @MapperScan(推荐))
[场景 2:单独使用 @Mapper(不推荐)](#场景 2:单独使用 @Mapper(不推荐))
[场景 3:同时使用 @Mapper+ @Repository(冗余)](#场景 3:同时使用 @Mapper+ @Repository(冗余))
[4. 关系总结](#4. 关系总结)
[实践(Spring Boot + MyBatis)](#实践(Spring Boot + MyBatis))
1. @Mapper
(MyBatis 注解)
-
作用:
标记在 Mapper 接口 上,告诉 MyBatis:"这个接口需要被扫描并生成动态代理实现类"。
-
责任方:
MyBatis 框架(通过
mybatis-spring
整合包)。 -
关键点:
-
必须配合 **
@MapperScan
** 或 XML 配置使用,否则 MyBatis 不会扫描该接口。 -
不涉及 Spring 容器管理(单纯标记接口,不注册 Bean)。
-
主要解决 "MyBatis 如何识别哪些接口需要生成代理类" 的问题。
-
2. @Repository
(Spring 注解)
-
作用:
标记在 类 上(通常是 DAO 实现类),告诉 Spring:"这是一个数据访问层组件,请注册为 Bean 并启用异常转换"。
-
责任方:
Spring Framework。
-
关键点:
-
属于 Spring 组件扫描的一部分(如
@ComponentScan
)。 -
自动启用 异常转换 (将 MyBatis/JDBC 异常转为 Spring
DataAccessException
)。 -
主要解决 "Spring 如何管理数据访问层 Bean" 的问题。
-
3. 二者在 MyBatis 项目中的协作关系
场景 1:使用 @MapperScan
(推荐)
@SpringBootApplication
@MapperScan("com.example.mapper") // MyBatis 扫描包
public class App { ... }
-
Mapper 接口:
// 无需加 @Repository!MyBatis 代理类已由 @MapperScan 注册为 Spring Bean public interface UserMapper { User selectById(Long id); }
-
为什么不需要
@Repository
?@MapperScan
会:-
扫描指定包下的接口;
-
让 MyBatis 为这些接口生成动态代理类;
-
自动将这些代理类注册为 Spring Bean (相当于完成了
@Repository
的注册功能)。 -
自动启用异常转换 (整合包已处理,无需
@Repository
)。
-
场景 2:单独使用 @Mapper
(不推荐)
@Mapper // 仅标记接口,但未配置扫描
public interface UserMapper { ... }
-
问题:
若未配置
@MapperScan
,MyBatis 不会生成代理类,Spring 也无法注册 Bean → 运行时报NoSuchBeanDefinitionException
。 -
解决方案:
必须添加
@MapperScan
或在配置文件中指定 Mapper 包路径。
场景 3:同时使用 @Mapper
+ @Repository
(冗余)
@Mapper
@Repository // 多余的!
public interface UserMapper { ... }
-
效果:
-
@Mapper
让 MyBatis 识别接口; -
@Repository
会被 Spring 扫描到,但注册的是接口本身(不是代理类),导致注入失败。
-
-
结论:
不要同时在 Mapper 接口上加
@Repository
!它既无法替代
@Mapper
的代理生成功能,又会干扰 Spring 对 MyBatis 代理 Bean 的识别。
4. 关系总结
注解 | 框架 | 作用对象 | 主要功能 | 是否必需 |
---|---|---|---|---|
**@Mapper ** |
MyBatis | 接口 | 标记需生成代理的 Mapper 接口 | 可选(可用 @MapperScan 替代) |
**@Repository ** |
Spring | 类 | 注册 DAO Bean + 异常转换 | 在 MyBatis 中不需要 |
**@MapperScan ** |
MyBatis-Spring | 包 | 扫描接口 → 生成代理 → 注册 Bean | 必需 (推荐替代 @Mapper ) |
实践(Spring Boot + MyBatis)
-
配置类添加
@MapperScan
:@SpringBootApplication @MapperScan("com.example.mapper") // 指定 Mapper 接口包 public class App { ... }
-
Mapper 接口无需任何注解:
// 不加 @Mapper 或 @Repository! public interface UserMapper { @Select("SELECT * FROM user WHERE id = #{id}") User selectById(Long id); }
-
Service 层直接注入:
@Service public class UserService { @Autowired private UserMapper userMapper; // 注入的是 MyBatis 代理对象 }
关键结论:
**
@Mapper
是 MyBatis 的"接口标识"** (可被@MapperScan
替代);**
@Repository
在 MyBatis 场景下完全不需要** (由@MapperScan
代理注册 + 异常转换);二者不要混用,避免冲突。