BaseMapper<T>通过编译期类型擦除、启动时自动扫描和注解驱动解析关联数据库表;T为User时,优先读@TableName,否则按默认规则(如User→user)推导表名,并依@TableField、@TableId等注解映射字段与主键。

MyBatis-Plus 的 BaseMapper<T> 是一个泛型接口,它的映射不是靠“手动配置”或“运行时指定”,而是通过 编译期类型擦除 + 启动时自动扫描 + 注解驱动解析 三者协同完成的。核心在于:T 是什么类,MyBatis-Plus 就按这个类的注解和命名规则,去推导它对应哪张表、哪些字段。
BaseMapper 泛型 T 是怎么关联到数据库表的?
BaseMapper<User> 中的 User 类,就是映射的起点。框架会:
检查
User类是否标注了@TableName("sys_user")
✅ 有:直接使用该表名
❌ 没有:按默认规则转——把User首字母小写变成user,即查user表-
扫描
User类所有字段,逐个匹配数据库列名- 默认驼峰转下划线(如
userName→user_name) - 若字段名不匹配,用
@TableField("real_column_name")显式指定
- 默认驼峰转下划线(如
-
主键字段必须存在,且标注
@TableId(否则启动报错)立即学习“Java免费学习笔记(深入)”;
- 常见类型:
@TableId(type = IdType.AUTO)(自增)、ASSIGN_ID(雪花ID)等
- 常见类型:
其他增强能力(逻辑删除、自动填充、乐观锁)也依赖对应字段上的注解,如
@TableLogic、@TableField(fill = FieldFill.INSERT)、@Version
Mapper 接口如何“生效”?
你写的 Mapper 接口本身不写 SQL,只继承 BaseMapper<T>:
@Mapper
public interface UserMapper extends BaseMapper<User> {
}关键点:
-
@Mapper或@MapperScan让 MyBatis-Plus 在启动时识别该接口 - Spring 容器会为它生成代理实现(
MybatisMapperProxy),内部根据User.class反射读取注解 + 表结构元信息 - 所有方法(如
selectById、insert)都基于User类型动态拼 SQL,无需 XML 或手写语句
实体类典型写法(带关键注解)
@Data
@TableName("sys_user") // 显式指定表名(可选)
public class User {
@TableId(type = IdType.AUTO)
private Long id;
@TableField("user_name") // 映射字段名 user_name
private String userName;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableLogic // 逻辑删除字段,默认值 0/1
private Integer deleted;
}只要这个类能被正确加载(在 @MapperScan 路径下或加了 @Mapper),BaseMapper<User> 就能精准绑定到 sys_user 表,并按注解规则处理字段。
不依赖注解的全局配置方式(简化重复工作)
如果多数表都有统一前缀(如 t_),可在 application.yml 中配置:
mybatis-plus:
global-config:
db-config:
table-prefix: t_这样 User 类即使没写 @TableName,也会自动映射到 t_user 表,省得每个实体都加注解。
不复杂但容易忽略


















