Java 实体类为何不建议使用 is 前缀命名?
你可能会发现一个有趣的现象:数据库中的逻辑删除字段明明叫 is_deleted,但自动生成的 POJO (Plain Old Java Object) 里的属性名却是 deleted。
这并不是 IDE 或者 ORM 框架抽风,而是一个经过深思熟虑的行业标准。
字段命名映射对比表
我们对比一下两种不同的 Java 命名方式对 API 和序列化的影响:
| 数据库字段 | Java 属性名 | 框架生成的 Getter 方法名 | JSON 结果 | 风险等级 |
|---|---|---|---|---|
is_deleted | deleted | getDeleted() / isDeleted() | {"deleted": 0} | 🟢 安全 |
is_deleted | isDeleted | isDeleted() | {"deleted": 0} (前缀丢失) | 🔴 高危 |
逻辑流程说明
当 JSON 框架(如 Jackson)尝试将对象转为字符串时,它的探测逻辑如下:
- 开始对象序列化
- 扫描类中的所有方法
- 判断方法名是否以
is或get开头 - 去掉
get/is前缀,将剩余首字母转为小写作为 Key - 检查 Key 与属性名是否一致
- 若不一致,产生反序列化失败风险;若一致,输出最终 JSON 数据
graph TD
A[开始对象序列化] --> B{扫描所有方法}
B --> C{方法名以 is/get 开头?}
C -- 是 --> D[去掉前缀并转小写]
C -- 否 --> E[忽略该方法]
D --> F{Key 与属性名一致?}
F -- 是 --> G[输出 JSON]
F -- 否 --> H[反序列化失败风险]
交互时序分析
如果强行在 Java 属性中使用 is 前缀,前端与后端之间的通信可能会发生严重的冲突:
- 后端:属性名为
isDeleted(Integer 类型),调用isDeleted()获取值。 - 序列化:发送 JSON
{"deleted": 1}(前缀被自动去掉了)。 - 前端:修改后传回数据报错:找不到该方法!或者由于 Key 不匹配导致赋值为 null。
- 反序列化:寻找
setIsDeleted()方法失败。
sequenceDiagram
participant Client as 前端页面
participant Server as 后端服务
participant Engine as 序列化引擎
Client->>Server: 提交 JSON {"isDeleted": 0}
Server->>Engine: 尝试反序列化
Engine-->>Server: 寻找 setIsDeleted() 方法
Server-->>Client: 报错:找不到该方法
Note over Client,Server: 跨服聊天问题
逻辑删除状态演进
在 MyBatis-Plus 的作用下,deleted 字段控制着数据的生命周期:
- 正常状态 (
deleted = 0):执行 SQL Delete 实际上是 Update 语句,将值改为 1。 - 已删除状态 (
deleted = 1):执行恢复操作或物理清理 (定时任务)。
实体类结构设计
以 MemberUser 为例,标准的 POJO 结构如下,利用注解解决 Database 映射问题:
public class MemberUser {
private Long id;
private String username;
private Integer deleted; // 推荐使用 Integer 而非 Boolean
public Integer getDeleted() {
return deleted;
}
public void setDeleted(Integer val) {
this.deleted = val;
}
}
配合 MyBatis-Plus 注解:
@TableField("is_deleted")
private Integer deleted;
核心知识要点
- 为什么不加 is 前缀?
- JavaBeans 规范限制:
isDeleted属性生成的 getter 依然是isDeleted(),导致 RPC 或序列化框架混淆。 - 阿里代码手册强制规定:禁止在 POJO 中布尔类型变量加
is。
- JavaBeans 规范限制:
- 如何处理映射?
- 使用注解:在 Java 属性上加
@TableField("is_deleted")。 - 逻辑删除注解:使用
@TableLogic标记该字段。
- 使用注解:在 Java 属性上加
- 数据类型建议
- 推荐使用 Integer:比 Boolean 更具扩展性(例如未来可能支持多种删除状态)。
- 包装类型:永远使用
Integer而不是int,防止默认值0产生的业务误判。
- 框架表现
- Jackson (JSON 处理框架):默认根据 getter/setter 推断字段名。
- Lombok (代码生成库):自动生成的 getter 名遵循规范,进一步暴露
is前缀的问题。

