一、核心概念

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 配合 TableNameParserDynamicTableNameParser 实现
多 schema 环境下表名错误 未设置 schema 属性 使用 @TableName(value = "table", schema = "tenant_001")

五、注意事项

  1. 包导入正确:必须导入 com.baomidou.mybatisplus.annotation.TableName,不是其他包。
  2. 大小写敏感:MySQL 在 Linux 下表名区分大小写,建议统一小写 + 下划线。
  3. 不要重复配置:若全局配置了 table-prefix,注意 keepGlobalPrefix 是否需要开启。
  4. @TableId 配合使用:主键字段建议使用 @TableId 明确标识。
  5. 避免中文表名:虽然支持,但易引发兼容性问题。

六、使用技巧

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 实现分库分表。


七、最佳实践

  1. 始终显式使用 @TableName
    即使表名与类名一致,也建议加上,提高可读性和维护性。

  2. 统一命名规范
    数据库表名使用小写 + 下划线(如 t_user_info),Java 类名使用大驼峰(如 UserInfo)。

  3. 配合 Lombok 使用
    减少样板代码,提升开发效率。

  4. 使用全局前缀 + 个别例外
    如所有业务表加 t_ 前缀,字典表加 d_,通过配置统一管理。

  5. 避免在生产环境开启 SQL 日志
    调试时开启 log-impl,上线后关闭,避免性能损耗。


八、性能优化建议

  1. 合理使用 @TableName + 缓存
    MyBatis-Plus 会缓存表结构信息,首次解析后性能无影响。

  2. 避免频繁动态表名解析
    动态表名会增加 SQL 解析开销,建议缓存解析结果或使用分库分表中间件。

  3. 结合 MyBatis 缓存
    开启二级缓存,减少对数据库的重复查询。

  4. 索引优化
    @TableName 虽不直接影响性能,但应确保对应表有合理索引,尤其是查询字段。


九、总结

项目 说明
核心作用 映射实体类与数据库表
是否必须 表名与类名不一致时必须
推荐用法 显式标注 + 全局前缀管理
高级用法 动态表名、多 schema 支持
性能影响 极小,主要在启动期解析

一句话掌握

当 Java 实体类名与数据库表名不一致时,使用 @TableName("实际表名") 显式指定映射关系,确保 MyBatis-Plus 能正确生成 SQL。