Spring Boot / MyBatis Mapper 层常用注解详解
在 Spring Boot 的三层架构中:
Controller → Service → Mapper/Dao
Mapper 层(也称 Dao 层)负责数据库访问 ,是应用程序与数据库交互的核心部分。
为了简化数据库操作,Spring Boot + MyBatis 提供了一系列注解与基类,帮助开发者快速开发。
本文将系统讲解:
@Mapper
@Repository
BaseMapper
@Select / @Insert / @Update / @Delete
@TableName / @TableId / @TableField
并分析 使用方式、使用场景、易错点与面试常考点。
一、@Mapper(MyBatis 核心注解)
1. 概念
@Mapper 用于标识 接口是 MyBatis 的 Mapper,Spring 会自动扫描并创建对应的实现类(代理对象),以便执行 SQL 操作。
2. 使用示例
java
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User getUserById(Long id);
@Insert("INSERT INTO user(name, age) VALUES(#{name}, #{age})")
int addUser(User user);
}
Spring Boot 启动时会:
- 扫描
@Mapper注解 - 为接口生成代理实现
- 注入到 Service 层
3. 使用场景
- 所有 MyBatis Mapper 接口 必须使用
@Mapper或者在启动类加@MapperScan扫描包。 - 适用于 自定义 SQL 注解(@Select / @Insert / @Update / @Delete)。
4. 易错点
- 忘记加 @Mapper 或者 @MapperScan
java
@Autowired
private UserMapper userMapper;
会报错:
NoSuchBeanDefinitionException
- 包扫描路径不对
@MapperScan("com.example.mapper") 必须指定 Mapper 所在包。
二、BaseMapper(MyBatis-Plus 基础 Mapper)
1. 概念
BaseMapper<T> 是 MyBatis-Plus 提供的 基础 CRUD Mapper,无需手写 SQL 即可完成常见数据库操作。
2. 使用示例
Mapper 接口
java
public interface UserMapper extends BaseMapper<User> {
}
Service 使用
java
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
通过继承 BaseMapper + ServiceImpl,自动获得:
java
save()
getById()
list()
updateById()
removeById()
3. 优点
- 减少 CRUD SQL 编写量
- 与 Service 层结合,开发效率高
- 兼容分页、条件构造器
4. 易错点
- 实体类未加 @TableName 或字段未加 @TableField,导致 MyBatis-Plus 无法映射表/字段。
- Mapper 没有继承 BaseMapper,就无法调用自动方法。
- 注入 Mapper 时未加 @Mapper 或 @MapperScan,导致 Spring 无法管理。
三、@Repository(Spring 注解)
1. 概念
@Repository 是 Spring 的 持久化层组件注解,主要作用:
- 标识 DAO / Mapper 层组件
- 自动转化异常,将 数据库异常转为 Spring DataAccessException
2. 与 @Mapper 的区别
| 注解 | 功能 | 使用场景 |
|---|---|---|
| @Mapper | MyBatis 注解,标识 Mapper 接口 | MyBatis Mapper 接口 |
| @Repository | Spring 注解,标识 DAO 组件,异常转换 | Spring 持久化层组件 |
| 结合使用 | MyBatis + Spring,可以同时使用 | Mapper + 统一异常管理 |
在 Spring Boot 项目中,如果使用
@MapperScan扫描 Mapper 包,一般 不必单独加 @Repository,因为 Spring 会自动生成 Bean。
四、@Select / @Insert / @Update / @Delete(SQL 注解)
1. 概念
MyBatis 提供的 注解方式写 SQL,避免 xml 文件管理。
2. 使用示例
java
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user WHERE age > #{age}")
List<User> getUsersOlderThan(int age);
@Update("UPDATE user SET age = #{age} WHERE id = #{id}")
int updateUserAge(Long id, int age);
@Delete("DELETE FROM user WHERE id = #{id}")
int deleteUser(Long id);
}
3. 使用场景
- SQL 简单、少量时可直接使用注解
- 避免维护大量 XML 文件
- 对动态 SQL 和复杂查询,推荐使用 XML 或 MyBatis-Plus 条件构造器
4. 易错点
- 参数名称与 SQL 占位符不一致
- 返回类型与 SQL 查询结果不匹配
- 注解写在 接口方法上,非类上
五、MyBatis-Plus 实体类注解
1. @TableName
java
@TableName("user")
public class User {
...
}
- 指定数据库表名
- 不加时,默认用类名转驼峰映射
2. @TableId
java
@TableId(value = "id", type = IdType.AUTO)
private Long id;
- 指定主键
- 支持自动生成策略(AUTO / ASSIGN_ID / ASSIGN_UUID)
3. @TableField
java
@TableField("user_name")
private String name;
- 映射数据库列
- 支持字段忽略、条件构造器等功能
六、Mapper 层最佳实践
MyBatis-Plus + BaseMapper
- Mapper 继承 BaseMapper
- Service 层继承 ServiceImpl
- 直接使用 CRUD 方法,无需 XML
复杂 SQL 使用 @Select / XML
- 动态查询、联表查询、聚合函数
- 保持 Mapper 简洁,XML 或注解分离业务逻辑
Spring Bean 扫描
@MapperScan("com.example.mapper")- 确保 Mapper 包被 Spring 管理
七、面试常见问题
@Mapper 和 @Repository 区别?
- @Mapper → MyBatis 注解,标识 Mapper 接口
- @Repository → Spring 注解,标识 DAO,统一异常管理
BaseMapper 有哪些方法?
- CRUD: save, getById, list, removeById, updateById
- 条件构造器查询: selectList, selectOne
MyBatis-Plus 注解 @TableName / @TableId / @TableField 有何作用?
- @TableName → 指定表名
- @TableId → 指定主键
- @TableField → 指定字段映射或忽略字段
@MapperScan 为什么比每个 Mapper 上加 @Mapper 更方便?
- 扫描包统一管理,减少重复注解
- 避免忘记 @Mapper 导致 Bean 注入失败
八、总结
Mapper 层核心注解可以总结为:
组件注解
java
@Mapper
@Repository(可选)
@MapperScan
CRUD 与 SQL
java
BaseMapper
@Select / @Insert / @Update / @Delete
实体映射
java
@TableName
@TableId
@TableField
这些注解配合 Spring + MyBatis-Plus,可以实现 快速 CRUD、复杂 SQL 映射以及事务管理,是企业级项目开发的核心工具。