Java封装数据库实体的核心是隐藏数据来源与实现细节,通过语义化方法(如getDisplayName、isActive)、业务方法整合DAO逻辑、接口+工厂隔离实现类、敏感字段运行时脱敏来实现。

Java 中封装数据库实体细节,核心不是把字段设成 private 就完事,而是让调用方根本不需要知道“数据从哪来、存在哪、怎么查、是否缓存”。真正的隐藏发生在方法行为里——接口稳定,内部可自由切换 JDBC、MyBatis、JPA 甚至远程服务。
用方法替代字段暴露,屏蔽数据来源
不要让外部直接访问 userId、createdAt 这类字段,而是提供语义明确的计算型方法:
-
getDisplayName():内部拼接nickname或 fallback 到username,不暴露原始字段名 -
isActive():综合判断status == 'ENABLED'且lastLoginTime >= 30 days ago,不暴露状态码或时间字段 -
getProfileUrl():根据avatarType和avatarId动态拼接 CDN 地址,外部只拿到一个可用 URL
把 DAO 层逻辑收进 Service 方法体内
数据库操作不该散落在各处,而应被封装在有业务含义的方法中:
-
changePassword(String raw):内部自动加盐哈希、更新密码失败时抛自定义异常、记录审计日志 -
assignToTeam(Team team):检查用户权限、校验团队容量、插入关联记录、触发通知——全部在一个方法里完成 -
getRecentOrders(int limit):第一次调用查库 + 缓存结果,后续走本地 Map 或 Redis,调用方无感知
用接口 + 工厂隐藏具体实现类
实体类本身可以轻量,真正隐藏细节靠抽象和模块边界:
立即学习“Java免费学习笔记(深入)”;
- 定义
UserView接口(只含getId()、getName()等只读方法),不暴露任何 setter 或数据库字段 - 实现类
JpaUserView或FeignUserView放在internal包或独立模块中,不对外导出 - 通过工厂或 Spring Bean 名称获取实例:
UserView user = UserViewFactory.of("admin-123"),调用方不依赖具体类型
敏感字段做运行时脱敏或拦截
对密码、身份证号、手机号等,不止是 private,更要切断非法访问路径:
- getter 方法返回
"***"或空字符串,而非真实值 - 使用 Lombok 的
@ToString.Exclude和 Jackson 的@JsonIgnore防止序列化泄露 - 在 MyBatis 的
resultMap中跳过敏感字段映射,或用@Select("SELECT id, name FROM user")明确指定列


















