一、核心概念
1. 什么是 @TableName
?
@TableName
是 MyBatis-Plus 提供的一个注解,用于显式指定实体类(Entity)与数据库表之间的映射关系。
- 默认情况下,MyBatis-Plus 会根据实体类名自动推断对应的数据库表名(如
User
类映射到user
表)。 - 当实体类名与数据库表名不一致时,必须使用
@TableName
显式指定。
2. 作用
- 指定实体类对应的数据库表名。
- 支持动态表名(如分表场景)。
- 支持 schema、schema + catalog 等高级配置。
3. 所在包
import com.baomidou.mybatisplus.annotation.TableName;
二、操作步骤(非常详细)
步骤 1:引入 MyBatis-Plus 依赖
确保项目中已引入 MyBatis-Plus 的核心依赖(以 Maven 为例):
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version> <!-- 推荐使用最新稳定版 -->
</dependency>
步骤 2:创建实体类(Entity)
例如创建一个用户实体类 User
:
package com.example.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("t_user") // 显式指定表名为 t_user
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
⚠️ 注意:如果数据库表名是
user
,而类名也是User
,可以省略@TableName
。
步骤 3:创建 Mapper 接口
package com.example.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
步骤 4:配置 MyBatis-Plus(Spring Boot)
在 application.yml
中配置数据源和 MyBatis-Plus:
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 控制台打印 SQL
步骤 5:使用 Service 层调用(可选)
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public List<User> getAllUsers() {
return userMapper.selectList(null);
}
}
步骤 6:验证是否生效
启动 Spring Boot 应用,调用上述方法,观察控制台输出的 SQL 是否为:
SELECT id,name,age,email FROM t_user
如果表名正确,说明 @TableName
已生效。
三、@TableName 注解的属性详解
属性 | 类型 | 说明 | 示例 |
---|---|---|---|
value |
String |
指定数据库表名(必填) | @TableName("t_user") |
schema |
String |
指定 schema(如 PostgreSQL) | @TableName(value = "user", schema = "public") |
keepGlobalPrefix |
boolean |
是否保留全局表前缀(见配置) | @TableName(value = "user", keepGlobalPrefix = true) |
autoResultMap |
boolean |
是否自动构建 resultMap | 一般不用 |
idType |
IdType |
主键策略(已废弃,推荐用 @TableId ) |
不推荐在此设置 |
四、常见错误与解决方案
错误现象 | 原因 | 解决方案 |
---|---|---|
报错:Table 'xxx.user' doesn't exist |
实体类未加 @TableName 或表名不匹配 |
添加 @TableName("实际表名") |
SQL 查询表名仍为类名(如 User ) |
注解未生效或拼写错误 | 检查注解是否导入正确包,类是否被扫描 |
分表时动态表名失败 | 未使用 TableNameHandler |
配合 TableNameParser 或 DynamicTableNameParser 实现 |
多 schema 环境下表名错误 | 未设置 schema 属性 |
使用 @TableName(value = "table", schema = "tenant_001") |
五、注意事项
- 包导入正确:必须导入
com.baomidou.mybatisplus.annotation.TableName
,不是其他包。 - 大小写敏感:MySQL 在 Linux 下表名区分大小写,建议统一小写 + 下划线。
- 不要重复配置:若全局配置了
table-prefix
,注意keepGlobalPrefix
是否需要开启。 - 与
@TableId
配合使用:主键字段建议使用@TableId
明确标识。 - 避免中文表名:虽然支持,但易引发兼容性问题。
六、使用技巧
1. 全局表前缀配置(application.yml)
mybatis-plus:
global-config:
db-config:
table-prefix: t_ # 所有表加 t_ 前缀
此时若实体类为 User
,默认映射到 t_user
,无需 @TableName
。
但若某个表不想加前缀,可使用:
@TableName(value = "user", keepGlobalPrefix = false)
public class User { ... }
2. 动态表名(分表场景)
适用于按月/按用户分表(如 log_202501
, log_202502
)。
配置动态表名解析器:
@Bean
public MybatisPlusPropertiesCustomizer plusPropertiesCustomizer() {
return plusProperties -> {
TableNameParser tableNameParser = sql -> {
// 动态替换表名
if ("com.example.mapper.LogMapper.selectList".equals(sql.getId())) {
return "log_" + DateUtil.format(new Date(), "yyyyMM");
}
return null; // 返回 null 表示不替换
};
plusProperties.getConfiguration().setTableNameParser(tableNameParser);
};
}
实体类仍使用 @TableName("log_202501")
,但运行时会被动态替换。
更推荐使用 ShardingSphere 实现分库分表。
七、最佳实践
始终显式使用
@TableName
即使表名与类名一致,也建议加上,提高可读性和维护性。统一命名规范
数据库表名使用小写 + 下划线(如t_user_info
),Java 类名使用大驼峰(如UserInfo
)。配合 Lombok 使用
减少样板代码,提升开发效率。使用全局前缀 + 个别例外
如所有业务表加t_
前缀,字典表加d_
,通过配置统一管理。避免在生产环境开启 SQL 日志
调试时开启log-impl
,上线后关闭,避免性能损耗。
八、性能优化建议
合理使用
@TableName
+ 缓存
MyBatis-Plus 会缓存表结构信息,首次解析后性能无影响。避免频繁动态表名解析
动态表名会增加 SQL 解析开销,建议缓存解析结果或使用分库分表中间件。结合 MyBatis 缓存
开启二级缓存,减少对数据库的重复查询。索引优化
@TableName
虽不直接影响性能,但应确保对应表有合理索引,尤其是查询字段。
九、总结
项目 | 说明 |
---|---|
核心作用 | 映射实体类与数据库表 |
是否必须 | 表名与类名不一致时必须 |
推荐用法 | 显式标注 + 全局前缀管理 |
高级用法 | 动态表名、多 schema 支持 |
性能影响 | 极小,主要在启动期解析 |
✅ 一句话掌握:
当 Java 实体类名与数据库表名不一致时,使用
@TableName("实际表名")
显式指定映射关系,确保 MyBatis-Plus 能正确生成 SQL。