【杂类】理解 @Repository 和 Mapper 的关系

目录

[​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会:

    1. 扫描指定包下的接口;

    2. 让 MyBatis 为这些接口生成动态代理类;

    3. ​自动将这些代理类注册为 Spring Bean ​(相当于完成了 @Repository的注册功能)。

    4. ​自动启用异常转换 ​(整合包已处理,无需 @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)​​

  1. ​配置类添加 @MapperScan:​​

    复制代码
    @SpringBootApplication
    @MapperScan("com.example.mapper") // 指定 Mapper 接口包
    public class App { ... }
  2. ​Mapper 接口无需任何注解:​​

    复制代码
    // 不加 @Mapper 或 @Repository!
    public interface UserMapper {
        @Select("SELECT * FROM user WHERE id = #{id}")
        User selectById(Long id);
    }
  3. ​Service 层直接注入:​​

    复制代码
    @Service
    public class UserService {
        @Autowired
        private UserMapper userMapper; // 注入的是 MyBatis 代理对象
    }

​关键结论​:

  • ​**@Mapper是 MyBatis 的"接口标识"​** ​(可被 @MapperScan替代);

  • ​**@Repository在 MyBatis 场景下完全不需要** ​(由 @MapperScan代理注册 + 异常转换);

  • 二者不要混用,避免冲突。

相关推荐
code2cat6 小时前
Java工具篇之Maven:从pom.xml到测试通过的JAR
xml·java·maven
wuminyu12 小时前
JVM规范学习总结:解释器与JIT编译器如何处理JVM字节码
java·linux·c语言·jvm·c++
txxzjmzlh12 小时前
SpringBoot 配置⽂件
java·spring boot·spring
Wang's Blog13 小时前
Java 项目实战: 交友项目 - 搜索附近的功能概述和分析
java·开发语言·交友
骑着蜗牛撵大象32713 小时前
大模型 Agent 的沙箱护栏:gVisor 隔离、出口白名单与审计闭环
java·开发语言·jvm·安全·agent沙箱·gvisor·microvm
独泪了无痕13 小时前
Hutool之LocalDateTimeUtil:让时间间隔操作如虎添翼
java
三无少女指南14 小时前
从这里开始:Java 后端与 AI 工程的三条阅读路线
java·学习路线·ai工程
香蕉大香蕉(06敬畏市场)15 小时前
MySQL 单点详解(07)
java·数据库·mysql·ai·博客·八股
nice_lcj52015 小时前
深入理解 Java 反射:从 Class 对象到方法调用(含性能实测 + 迷你 IOC 实战 + 面试考点)
java·开发语言·后端·面试
骑着蜗牛撵大象32716 小时前
2026 后端 AI 工程化:Spring AI 管调用、MCP 管工具、Agent 内嵌管自治
java·人工智能·后端·spring·ai·可观测性·mcp