一、我是谁,以及我遇到了什么问题
我是业务后端开发,日常负责公司电商中台的订单域维护。日常工作就是排期内的需求开发、接口联调和修一些小Bug,技术栈是 Spring Boot + MyBatis-Plus + Redis + Dubbo。
上周三上午,产品提了一个很“日常”的需求:订单详情接口需要多返回一个“优惠分摊金额”字段,前端要在订单页展示。需求文档就一句话:“订单详情的优惠券模块,增加实际分摊金额。”
听起来很简单对吧?但这个订单系统已经经历了三任开发,代码里充满了各种 OrderVO、OrderDetailVO、OrderExtVO、OrderQueryDTO……DTO 类多达六七个。真正的数据链路是:Mapper.xml 联表查出来 → 塞进 Entity → 经过 Service 转换成 DetailDTO → 再经过 Converter 映射成 OrderDetailVO → 最终返回给前端。
我自己翻代码捋这条链路,至少半小时起步,而且最大的痛点是:我老记不住 VO 里哪个字段对应数据库哪一列,改漏一个 Mapper.xml 里的 resultMap 字段,联调时就是字段为 null,特别丢人。以前做这种需求,改代码 20 分钟,联调被前端追着问“怎么是 null”再排查 20 分钟,纯纯的无效耗时。
二、我是怎么用 TraeCode 解决这件事的
这次我用了 IDE 模式,因为我需要它帮我梳理现有链路,然后在它给出的“修改清单”上逐项确认。我不希望它直接替我把所有代码改了,因为涉及线上业务,我必须要过目每一处改动。
第一步:让 TraeCode 帮我“理清血缘关系”
我没有直接说“给我加个字段”,而是先给上下文:
“当前项目是 Spring Boot + MyBatis-Plus。订单详情接口是
/order/detail/{id},对应 Controller 是OrderController#detail。请帮我梳理:从数据库查询到返回给前端 JSON,中间经过哪些类、哪些转换方法?把数据流向图画出来,并列出每一层当前映射了哪些字段。”
TraeCode 很快给出了一个清晰的链路图:
-
DB →
OrderMapper.xml(联表查询,resultMap配置了 20+ 字段) -
DO (
OrderEntity+OrderExtEntity) -
Service (
OrderServiceImpl) 组装,调用OrderConverter -
DTO (
OrderDetailDTO,内部包含CouponInfo子对象) -
VO (
OrderDetailVO) 最终返回
它甚至贴心地指出:当前 CouponInfo 子对象里只有 couponId 和 discountAmount,并没有“分摊金额”字段,需要先在 DTO 和 VO 里补上。
这一步如果自己干,我要开着 IDE 全局搜索 OrderDetailVO,再点开 Converter 看映射,再点开 Mapper 看 XML,哪怕很熟练也要 15 分钟。TraeCode 10 秒整理成表格。
第二步:让 TraeCode 生成“修改检查清单”
我接着输入:
“很好。现在我要加一个字段
shareAmount(BigDecimal)。请帮我列出所有需要修改的文件清单,以及每个文件具体要改什么地方。不要直接改代码,先出清单。”
TraeCode 输出了一个极为清晰的清单:
-
SQL / 实体层:
OrderMapper.xml的BaseResultMap中增加<result column="share_amount" property="shareAmount"/>;OrderEntity增加shareAmount属性(如果 DB 已有列则忽略 DDL,若没有需加 ALTER)。 -
DTO 层:
OrderDetailDTO内部的CouponInfo类增加shareAmount字段。 -
转换层:
OrderConverter.java的toDetailVO方法中,增加vo.setShareAmount(dto.getCouponInfo().getShareAmount())。 -
VO 层:
OrderDetailVO内部的CouponInfoVO增加shareAmount字段。 -
(可选)单元测试:更新 Mock 数据。
它甚至还提醒我:“注意检查 OrderConverter 是否使用了 MapStruct,如果是,需要修改接口定义而非手写 set。”
第三步:逐项执行,TraeCode 帮我写具体代码
针对清单里的每一项,我分别让它生成代码片段:
-
Mapper.xml:我让它参照现有的
discount_amount写法,生成标准字段映射,并提示我检查sql片段里的select列名是否包含该字段。 -
Entity/DTO/VO:生成标准的
private BigDecimal shareAmount;并补全getter/setter(我用的 Lombok,它自动跳过了)。 -
Converter:它帮我生成了转换语句,还顺带加了一个 null 判空处理(
Optional.ofNullable(...).orElse(BigDecimal.ZERO)),这是我自己写经常会忘的健壮性细节。
第四步:本地启动 + 自测验证
改完后,我让 TraeCode 帮我生成一条测试用的 JSON 入参和返回体结构,方便我直接用 Postman 验证。我本地启动服务,断点到 Converter 层,确认 shareAmount 成功从 DB 值映射到了最终返回的 JSON 里。整个过程没有任何字段为 null 的尴尬情况。
最后我让它帮我 review 本次变更:
“请 review 我本次修改的所有文件,检查是否有遗漏 setter 或者类型不匹配的问题。”
它扫了一遍,指出我在 OrderDetailDTO 里加了字段,但在 OrderConverter 中取值的链式调用写成了 dto.getShareAmount()(实际上应该从 dto.getCouponInfo().getShareAmount() 取),这是一个严重的低级错误,我自己肉眼 review 绝对漏看,TraeCode 帮我提前揪出来了。
三、成果展示
最终我交付了:
-
5 个文件修改:1 个 Mapper.xml、1 个 Entity、1 个 DTO、1 个 VO、1 个 Converter。
-
1 份变更影响范围说明(由 TraeCode 生成初稿,我微调),贴在 MR 描述里,方便 Code Reviewer 知道改了哪些层级。
-
1 个手工测试通过的截图(Postman 返回体包含新字段)。
这个结果解决了前端“取不到分摊金额”的阻塞问题。代码当天上午改完,下午和前端联调 5 分钟就通过了,没有来回拉扯。目前该接口已在测试环境验证通过,等待下个迭代发版。
四、效率对比
以前这种需求,我最怕的就是在 Converter 里写错取值对象(取到了父对象而不是子对象),导致前端拿到的字段永远是 null,然后被 QA 打回来。这次因为 TraeCode 帮我梳理清楚了 CouponInfo 的层级关系,并在 Review 时提前捕获了错误,一次性通过自测。
五、经验和技巧总结(针对日常开发)
1. 切忌上来就让它“帮我改代码”。 日常开发最大的成本不是写代码,而是“找对地方”。一定要先用提示词逼它输出“修改清单”和“数据流向图”。清单出来之前,绝不松口让它动代码。清单就是你和 AI 之间的“合同”,你审核清单没问题了,再让它按清单执行。
2. 对于 DTO/VO 转换场景,一定要强调“检查层级关系”。 我的教训是,直接说“加字段”,它可能会在顶层 DTO 加,而不是嵌套对象里加。必须明确告诉它:“这个字段属于子对象 CouponInfo,请基于现有结构修改。” 上下文给得越细,它改得越准。
3. 改完后一定让它做一次“变更影响面 Review”。 日常开发最容易遗漏的就是 MapStruct 或手写 Converter 里的 set 语句。让 TraeCode 把“新增的字段”在每一层的映射路径重新走一遍,它能像断点一样帮你检查有没有断层。这比运行时报错才发现要快得多。