一、@Mapper和@Repository区别
在Spring框架中,@Mapper 和 @Repository 都是用来标注持久层(数据访问层)组件的注解,但它们的使用场景和功能有所不同。
1、@Mapper
1、@Mapper 是 MyBatis 框架提供的注解,用于标记接口作为数据访问对象(DAO)。它会让 MyBatis 自动生成实现类,并通过接口方法映射 SQL 查询或更新操作
2、主要功能是将接口方法与 SQL 语句进行关联(通过 XML 配置文件或者注解),让 MyBatis 自动为接口创建代理实现类
3、通常配合 @MapperScan 注解或在 Spring 配置中启用 MyBatis 扫描接口(@MapperScan 会扫描指定包下所有的 @Mapper 注解的接口)
@Mapper
public interface UserMapper {
User selectUserById(int id);
}
2. @Repository
1、@Repository 是 Spring 框架提供的注解,用于标记数据访问层的组件。它通常用于 DAO 类上,指示该类是持久化层的一个组件,Spring 会自动将其注册为 Spring Bean。
2、该注解本身并不会生成接口的实现,而是用于注解一个具体的 DAO 类,使其成为 Spring 管理的 Bean。
3、@Repository 是 @Component 的一种特化注解,表示该类负责数据库操作,同时还会做一些持久化相关的异常转换(将 JDBC 异常转为 Spring 的 DataAccessException)。
@Repository
public class UserRepository {
// 数据库操作代码
}
总结区别:
框架不同:
@Mapper是 MyBatis 提供的注解,用于映射 SQL 操作。@Repository是 Spring 提供的注解,表示数据访问组件,并用于 Spring 的 Bean 管理。
功能不同:
@Mapper使 MyBatis 自动生成接口实现,主要用于简化数据访问操作。@Repository用于标记 DAO 类,并为其提供异常转换功能。
使用场景:
@Mapper主要用于 MyBatis 的接口层。@Repository主要用于 Spring Data JPA 或 Hibernate 等框架的 DAO 类层,或者自定义的持久化层组件。
二、@Mapper和@MapperScan必须同时存在吗?
@Mapper 和 @MapperScan不必须同时存在,但它们通常是配合使用的。它们的功能是不同的,使用时可以根据项目需求选择是否同时使用。
1、@MapperScan:
@MapperScan 是用来指定 MyBatis 要扫描的 Mapper 接口的包。它是一个类级别的注解,通常放在 Spring Boot 启动类上,或者配置类中,指定 MyBatis 要扫描的 Mapper 接口包路径。
@MapperScan用于批量扫描指定包下的所有接口,并自动为这些接口生成代理类,而无需在每个接口上都添加@Mapper注解。如果你使用了
@MapperScan,就不需要在每个 Mapper 接口上添加@Mapper注解了。@MapperScan会自动扫描该包下的所有接口,并将它们注册为 Mapper。
@SpringBootApplication
@MapperScan("com.example.mapper") // 扫描该包下所有的 @Mapper 接口
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
是否必须同时存在?
如果使用
@MapperScan,就不需要在每个 Mapper 接口上单独加上@Mapper注解。@MapperScan会自动扫描指定包下的所有接口,并注册为 Mapper 接口。如果不使用
@MapperScan,则需要在每个 Mapper 接口上加上@Mapper注解。这样 MyBatis 才会识别并生成相应的实现类。
总结:
可以独立使用:你可以选择使用
@Mapper或@MapperScan中的一个,具体取决于你的项目需求。如果你想手动控制哪些接口是 Mapper,或者你的接口数量较少,可以在每个 Mapper 接口上使用
@Mapper注解。如果你想批量扫描多个接口,并避免每个接口都写
@Mapper,则可以使用@MapperScan注解来一次性扫描指定包中的所有 Mapper 接口。
但两者并不必须同时使用,选择其中一个即可。
三、@Mapper和@Repository对于自动注入的区别
使用 @Mapper 注解可以解决利用@Autowired自动注入时的 警告问题。具体来说,@Mapper 注解在 MyBatis 中的作用不仅仅是标记接口是 MyBatis 的 Mapper,还涉及到接口的动态代理生成。它能确保 Spring 和 MyBatis 正确集成,从而使得你可以直接通过 @Autowired 注入 Mapper 接口,而不会出现警告或错误。
为什么会有警告?
通常,@Autowired 是按照 类型 来注入依赖的,而你提到的 动态代理类 实际上是 MyBatis 在运行时为接口生成的代理对象。这是因为 MyBatis 通过代理模式来实现对数据库操作的动态实现。
你可能会遇到警告或错误,提示接口没有实现类,这是因为 Spring 在启动时并不知道接口是由 MyBatis 生成的动态代理对象。
如果不加
@Mapper注解,Spring 会尝试按常规方式(基于接口类型)去查找对应的实现类,而这个实现类通常是由 MyBatis 动态生成的代理类。所以 Spring 在注入时会出现警告,认为这个接口没有具体的实现类。
@Mapper 解决的具体问题:
@Mapper注解告诉 Spring 容器,这个接口是一个 MyBatis 的 Mapper 接口,并且 MyBatis 会动态生成该接口的实现类(即代理类)。Spring 在扫描到
@Mapper注解后,会将该接口与 MyBatis 生成的代理类关联,确保你可以通过@Autowired注入该接口时,Spring 能正确地找到 MyBatis 动态生成的实现类。
如何避免警告?
当你在 Mapper 接口上加上 @Mapper 注解,Spring 会知道该接口是 MyBatis 的 Mapper 接口,进而允许你通过 @Autowired 正常注入,不会出现警告。
@Mapper
public interface UserMapper {
User selectUserById(int id);
}
为什么这样有效?
@Mapper注解的作用就是告诉 Spring 和 MyBatis,当前接口是 MyBatis 的 Mapper 接口,而 MyBatis 会为这个接口生成动态代理类。在 Spring 初始化时,Spring 容器会知道该接口是需要通过 MyBatis 自动注入的。Spring 与 MyBatis 集成:如果你使用了
@Mapper注解,并且配置了@MapperScan(或者在配置类中启用了 MyBatis 扫描功能),Spring 会自动处理 Mapper 接口与 MyBatis 代理实现的关系,从而避免注入时出现警告。
浙公网安备 33010602011771号