网站推广步骤有哪些工程信息价查询网站

张小明 2026/1/10 1:59:41
网站推广步骤有哪些,工程信息价查询网站,wordpress seo怎么写,编程软件下载手机版搞懂 Java 中的 VO、BO、PO、DTO、DO#xff1a;一个八年 Java 开发的踩坑与总结摸爬滚打八年 Java 开发#xff0c;从最初在老项目里对着一堆 “User”“UserInfo” 类一脸懵#xff0c;到现在能在新项目里清晰定义各种 “O” 的边界#xff0c;中间踩过的坑、排查过的诡异…搞懂 Java 中的 VO、BO、PO、DTO、DO一个八年 Java 开发的踩坑与总结摸爬滚打八年 Java 开发从最初在老项目里对着一堆 “User”“UserInfo” 类一脸懵到现在能在新项目里清晰定义各种 “O” 的边界中间踩过的坑、排查过的诡异 Bug多半都和这些 “数据载体类” 的混乱有关。见过实习生把 PO 直接返回给前端导致抓包能拿到数据库密码也维护过 DTO 和 VO 混用的老项目前端要自己格式化日期、拼接状态描述吐槽 “后端能不能多做点事”更遇到过 BO 层没封装好业务逻辑服务层代码里全是零散的 DO 操作改一个需求要动五六个地方 —— 今天就用最实在的场景把这几个 “O” 讲透让你少走弯路。先破后立别死记定义先看 “什么时候用”很多新手一开始就背 “PO 是持久化对象对应数据库表”但到了项目里还是会乱。我的经验是先想 “这个类要解决什么问题”再对应到具体的 “O”。比如 “数据要存数据库”→PO“要给前端展示”→VO顺着场景走比背定义管用 10 倍。1. POPersistent Object数据库的 “影子”别乱改PO 是和数据库表强绑定的对象简单说就是 “表结构转 Java 类”—— 表有什么字段PO 就有什么属性连字段名、类型都要一一对应比如数据库 varchar 对应 Stringdatetime 对应 LocalDateTime。核心场景ORM 映射MyBatis、JPA比如数据库有张user表字段名类型idbigintusernamevarchar(50)passwordvarchar(100)create_timedatetime对应的 UserPO 就该是这样用 Lombok 减少模板代码kotlin体验AI代码助手代码解读复制代码Data Table(name user) // 明确对应数据库表 public class UserPO { Id private Long id; private String username; private String password; // 数据库有这个字段PO就必须有 Column(name create_time) // 字段名不一致时指定 private LocalDateTime createTime; // 重点千万别加非数据库字段 // 比如别加private ListUserOrder orders; 这会让MyBatis查错 }八年踩坑教训曾经有个实习生在 UserPO 里加了private String statusDesc想存 “正常 / 禁用” 的描述结果 MyBatis 查询时报 “Unknown columnstatus_desc in field list”排查了 2 小时才发现是 PO 乱加字段。PO 只做 “数据容器”绝对不能加业务逻辑比如getTotalAmount()这种计算方法它的唯一职责就是 “装数据库里的数”。2. DODomain Object业务领域的 “主角”别和 PO 混了很多人会把 DO 和 PO 搞混 —— 其实 PO 是 “数据库的影子”而 DO 是 “业务的核心”。比如 “订单” 这个业务领域PO 是OrderPO对应order表字段而 DO 是OrderDO它会包含业务属性和业务逻辑甚至不依赖数据库结构。核心场景业务逻辑封装比如订单状态判断、金额计算还是订单例子OrderPO里只有order_statusint 类型1 待支付2 已支付...但OrderDO会把它封装成枚举还加业务方法kotlin体验AI代码助手代码解读复制代码Data public class OrderDO { // 基础属性可以从OrderPO转换过来 private Long id; private Long userId; private BigDecimal amount; // 业务属性用枚举替代int更直观 private OrderStatusEnum orderStatus; private LocalDateTime payTime; // 业务逻辑方法这是DO的核心价值 // 判断订单是否可取消已支付且未发货才能取消 public boolean isCancelable() { return OrderStatusEnum.PAID.equals(this.orderStatus) Objects.isNull(this.shipTime); } // 计算订单实付金额比如减去优惠券 public BigDecimal calculateActualPay(BigDecimal couponAmount) { return this.amount.subtract(couponAmount).max(BigDecimal.ZERO); } }关键区别PO 是 “数据载体”无业务逻辑DO 是 “业务载体”有业务逻辑。一个 DO 可能对应多个 PO比如UserDO可能包含UserPO基本信息和UserAddressPO地址信息的整合数据。我在电商项目里一开始没分 PO 和 DO直接用 PO 写业务逻辑后来改订单状态枚举时要改所有用到order_status的地方改成 DO 后只需要在 DO 里维护枚举清爽多了。3. DTOData Transfer Object数据传输的 “快递员”别多带东西DTO 是跨层、跨服务传输数据用的 —— 比如前端调后端接口Controller→前端、微服务之间调用ServiceA→ServiceB它的核心是 “按需传输”只传需要的字段不多传一个也不少传一个。核心场景 1接口请求RequestDTO前端提交创建用户的表单只需要username、phone、password那CreateUserRequestDTO就只定义这三个字段less体验AI代码助手代码解读复制代码Data Validated // 配合JSR380做参数校验很实用 public class CreateUserRequestDTO { NotBlank(message 用户名不能为空) Length(min 2, max 20, message 用户名长度2-20位) private String username; NotBlank(message 手机号不能为空) Pattern(regexp ^1[3-9]\d{9}$, message 手机号格式错误) private String phone; NotBlank(message 密码不能为空) Length(min 6, max 32, message 密码长度6-32位) private String password; }核心场景 2接口响应ResponseDTO后端返回用户信息给前端绝对不能传password所以UserResponseDTO要剔除敏感字段kotlin体验AI代码助手代码解读复制代码Data public class UserResponseDTO { private Long id; private String username; private String phone; private LocalDateTime createTime; // 只传需要的比如前端要显示注册时间 // 没有password没有password没有password }八年血泪教训维护过一个老项目接口直接返回UserPO结果 Swagger 里能看到password字段虽然前端没显示但抓包能抓到 —— 紧急改成UserResponseDTO才避免安全风险。别用Map当 DTO以前有同事图省事接口返回MapString, Object结果前端不知道哪些字段必返文档也没法生成后期维护全靠猜最后还是改成了 DTO。4. BOBusiness Object服务层的 “工具人”别让业务散了BO 是服务层Service内部用的 “业务对象”主要用来整合多个 DO/DTO 的数据避免服务层代码里到处都是零散的对象操作 —— 简单说就是 “把服务层需要的所有数据装在一起方便处理”。核心场景复杂业务整合比如订单确认、秒杀下单秒杀下单时服务层需要哪些数据OrderDO订单信息、UserDO用户信息、InventoryDO库存信息、CouponDO优惠券信息—— 如果每次处理都要单独查这四个对象代码会很散这时候就需要SeckillOrderBOjava体验AI代码助手代码解读复制代码Data public class SeckillOrderBO { // 整合多个业务对象 private OrderDO orderDO; private UserDO userDO; private InventoryDO inventoryDO; private CouponDO couponDO; // 还可以加一些服务层需要的临时属性 private boolean isNewUser; // 是否新用户用来判断是否给额外优惠 private BigDecimal seckillPrice; // 秒杀价和普通价区分 }为什么需要 BO秒杀项目里一开始没搞 BO服务层方法参数要传orderId、userId、couponId然后在方法里分别查OrderDO、UserDO、CouponDO代码里全是getById()后来封装成SeckillOrderBO方法参数只剩一个 BO代码瞬间清爽还减少了数据库查询次数。BO 只在服务层内部用不对外暴露比如不能传给 Controller也不能跨服务传输它是服务层的 “内部工具”。5. VOView Object前端展示的 “化妆师”别让前端干活VO 是给前端展示用的比 DTO 更贴近页面 —— 它会包含前端需要的格式化数据比如日期转字符串、金额加单位还可能组合多个 DTO 的数据让前端 “拿过来就能用”。核心场景页面展示比如用户详情页、订单列表页用户详情页需要什么UserResponseDTO的基本信息加上 “订单数量”“收藏商品数量”“会员等级描述”—— 这些数据来自不同 DTO所以需要UserDetailVOtypescript体验AI代码助手代码解读复制代码Data public class UserDetailVO { // 基本信息来自UserResponseDTO private Long id; private String username; private String phone; // 格式化数据前端不用自己转日期 JsonFormat(pattern yyyy-MM-dd HH:mm) private LocalDateTime createTime; // 组合数据来自OrderCountDTO、CollectCountDTO private Integer orderCount; // 订单数量 private Integer collectCount; // 收藏数量 // 业务描述前端不用自己判断会员等级 private String memberLevelDesc; // 比如“黄金会员”“钻石会员” // 格式化金额前端不用自己加单位 private String availableBalance; // 比如“¥198.00” }关键区别DTO vs VODTO 是 “传输用”关注数据正确性VO 是 “展示用”关注前端易用性。以前项目里有人把 DTO 和 VO 混用前端拿到createTime是时间戳每次都要自己转格式后来规范了 VO前端开发效率直接提升 30%—— 别让前端做后端该做的事一张表理清所有 “O”别再混淆了类型核心作用使用场景关键注意点PO数据库映射DAO 层和数据库交互字段和表严格对应无业务逻辑不对外暴露DO业务逻辑封装领域层 / 服务层内部包含业务属性和方法是业务核心DTO跨层 / 跨服务数据传输Controller、微服务调用剔除敏感字段只传必要数据不用 Map 替代BO服务层业务数据整合服务层内部聚合多个 DO/DTO不对外暴露VO前端展示数据格式化Controller 返回前端包含格式化数据、展示描述贴近页面需求八年开发的实战建议别只懂理论要落地用工具减少重复劳动手动写 DO→DTO→VO 的转换代码dto.setId(do.getId())太容易错用MapStruct自动转换比如kotlin体验AI代码助手代码解读复制代码Mapper(componentModel spring) public interface UserConverter { // 自动把UserDO转成UserResponseDTO UserResponseDTO doToResponseDto(UserDO userDO); // 自动把UserResponseDTOOrderCountDTO转成UserDetailVO Mapping(source orderCountDTO.count, target orderCount) UserDetailVO toDetailVO(UserResponseDTO userDTO, OrderCountDTO orderCountDTO); }用Lombok的Data减少getter/setter但别用AllArgsConstructor容易因为参数顺序错出 Bug。小项目可以灵活但别乱如果是个人项目或小项目DTO 和 VO 可以暂时混用比如简单接口直接返回 VOPO 和 DO 也可以合并如果业务简单—— 但中大型项目必须严格区分不然后期维护就是 “火葬场”。命名规范要统一别一会叫UserInfo一会叫UserData统一后缀UserPO、UserDO、CreateUserRequestDTO、UserResponseDTO、UserDetailVO—— 看到后缀就知道用途团队协作效率高。最后核心原则就一句话“每个‘O’都有自己的职责别让它干不属于它的活”——PO 别加业务逻辑DTO 别传敏感数据VO 别让前端格式化。我从一开始乱用词到现在能在项目里制定 “数据对象规范”靠的就是踩过的坑、吃过的亏。其实这些 “O” 不是教条而是前人总结的 “避坑经验”—— 规范做好了后期改需求、查 Bug 都会轻松很多。如果你的项目里还在乱用这些 “O”不如从今天开始先把 PO 和 DTO 的边界划清楚慢慢迭代优化 —— 好的代码不是一次写成的而是慢慢规范出来的。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

巩义网站建设方案报价濮阳网站建设电话

Linux内核动态调试终极指南:从入门到实战精通 【免费下载链接】linux Linux kernel source tree 项目地址: https://gitcode.com/GitHub_Trending/li/linux 还在为Linux内核崩溃后无从下手而苦恼?面对系统卡顿、死锁、内存泄漏等棘手问题&#xf…

张小明 2026/1/7 21:45:24 网站建设

腾讯云10g数字盘做网站够么深圳深圳网站建设

BiliTools AI视频总结功能:3个技巧让你高效学习B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持视频、音乐、番剧、课程下载……持续更新 项目地址: https://gitcode.com/GitHub_Trending/bilit/Bil…

张小明 2026/1/10 0:01:32 网站建设

做销售在哪个网站找客户快排seo排名软件

FaceFusion镜像内置水印系统:版权保护新机制 在AI生成内容(AIGC)爆发式增长的今天,一张由算法“换脸”生成的照片或一段深度合成视频,可能只需几秒就能完成。然而,当这些内容被恶意传播、伪造身份甚至用于诈…

张小明 2026/1/8 18:27:18 网站建设

如何判断网站有cdn加速嘉兴app开发公司

如何快速部署Qwen3-32B-GGUF:免费开源大语言模型完整实战指南 【免费下载链接】Qwen3-32B-GGUF 项目地址: https://ai.gitcode.com/hf_mirrors/Qwen/Qwen3-32B-GGUF 想要在本地环境中轻松获得强大的AI对话和文本生成能力吗?Qwen3-32B-GGUF作为阿…

张小明 2026/1/7 21:46:20 网站建设

智慧建设网站网站备案单位的联系方式

如何通过模型剪枝技术进一步提升推理效率? 在当今AIGC浪潮中,语音合成系统正以前所未有的速度走进我们的日常生活——从智能助手到有声读物,从虚拟主播到实时翻译。然而,一个现实问题始终困扰着开发者:大模型虽强&…

张小明 2026/1/7 21:16:08 网站建设

建设网站和别人公司重名网站域名怎么购买吗

第一章:Open-AutoGLM网络弹窗误判修复在使用 Open-AutoGLM 框架进行自动化任务时,部分用户反馈浏览器环境中频繁出现“网络连接异常”弹窗,经排查该提示为误判所致。此问题主要源于框架默认的网络状态检测机制对临时性请求延迟过于敏感&#…

张小明 2026/1/8 18:27:13 网站建设