Java实体类通过@Transient(JPA)、@TableField(exist=false)(MyBatis-Plus)等注解明确排除非数据库字段,实现内存与持久化的逻辑隔离;根本解法是DTO与Entity职责分离。

Java 实体类本身不“隐藏”数据库字段,而是通过明确声明哪些字段**不参与持久化**来实现逻辑隔离。关键不是遮掩,而是精准控制映射边界——让 ORM 框架清楚知道:这个字段只在内存中用,不进 SQL,不出 ResultSet。
用 @Transient 标记纯内存字段(JPA/Hibernate 场景)
这是最直接、标准的方式。加上 @Transient 后,该字段完全退出 ORM 生命周期:不会出现在 INSERT/UPDATE 语句里,查询结果也不会尝试填充它。
- 必须导入
javax.persistence.Transient - 可加在字段上,也可加在 getter 方法上(效果一致)
- 注意与 Lombok 冲突:@Data 生成的 toString() 仍会打印该字段,敏感值需额外处理
用 @TableField(exist = false) 排除非数据库字段(MyBatis-Plus 场景)
MyBatis-Plus 提供了更贴合自身生态的注解。@TableField(exist = false) 明确告诉框架:“这个字段没对应列,别查也别插”。它比 @Transient 更具语义性,且不影响 Jackson 序列化。
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- 仅对 MyBatis-Plus 生效;原生 MyBatis 需配合
<resultMap>手动排除 - 字段仍可正常 get/set,适合传输中间态数据(如密码明文、验证码)
- 若字段名与数据库列同名但不想映射,此注解比改名更安全
避免混用 DTO 和 Entity(设计层面的根本解法)
很多“需要隐藏字段”的需求,其实源于把接收参数的 DTO 和操作数据库的 Entity 合并在一个类里。正确做法是职责分离:
立即学习“Java免费学习笔记(深入)”;
- Controller 层用专门的 DTO 接收前端数据(含 passwordConfirm、captcha 等)
- Service 层校验后,将必要字段复制到干净的 Entity 中再交由 DAO 操作
- Entity 里只保留真实映射字段 + 少量必需的 transient 辅助字段
自定义注解 + 反射过滤(高阶可控方案)
当框架默认机制不够用(比如需动态控制某些字段是否入库),可定义如 @NonDatabaseField 注解,再配合工具类在组装参数或构建 ResultMap 前扫描并剔除标记字段。
- 适用于统一拦截场景(如审计字段自动注入、多租户字段过滤)
- 需自行维护反射逻辑,增加复杂度,建议仅在通用 SDK 或基础框架中使用
- 运行时生效,不依赖特定 ORM,扩展性强

















