AI 帮你写了 480 个文件,然后你发现加一个字段要改好几个地方
一、AI 写 CRUD 最大的坑:它只管生,不管养
先来看一个标准的 MyBatis-Plus 项目结构,一张 user 表,常规需要这些文件:

复制代码UserEntity.java → 实体类
UserDTO.java → 传输对象
UserMapper.java → Mapper 接口
UserMapper.xml → SQL 映射文件
UserService.java → 业务接口
UserServiceImpl.java → 业务实现
6 个文件,AI 一口气帮你生成,速度确实快。80 张表就是 480 个文件,AI 几分钟就能搞定。
但真正的问题在后面等着你。
产品经理一句“用户表加个 remark 字段”,就能让你忙活好一阵:
复制代码1. UserEntity.java — 加字段 → AI 能帮你改
2. UserDTO.java — 加字段 → AI 也能帮你改,但你得告诉它
3. UserMapper.xml — 检查 SQL 是否用到 select *
4. UserServiceImpl.java — 检查是否手动拼接了字段
更麻烦的是,同样的改动在其他 79 张表的关联查询里也要走一遍——因为可能有 JOIN user 表的 SQL 散落在各张表的 Mapper.xml 里。
AI 帮你生成代码的时候,你省下了时间。但 AI 不帮你维护代码一致性的时候,你之前省下的时间,全得加倍还回去。
所以,问题的核心不在于“AI 写的代码质量如何”,而在于代码的变更面究竟有多大。一个字段分散在 6 个文件里,你改就得改 6 个文件——不管这 6 个文件是谁写的,AI 还是你自己。
二、不是 MyBatis 的锅,是「文件数」本身就是变更成本
有人可能会说,“这不能怪 MyBatis 设计不好,用 JPA 会不会好点?” 我们来做个对比:
| 方案 | 一个表最少几个文件 | 加一个字段要检查几处 |
|---|---|---|
| MyBatis 手动写 | 4-6 个 | Entity + DTO + Mapper.java + Mapper.xml + 手工拼接处 |
| MyBatis-Plus 代码生成 | 4-6 个 | Entity + DTO + Mapper + Service(生成器可能漏改) |
| JPA / Hibernate | 2-3 个 | Entity + DTO + 自定义 @Query |
| jOOQ 代码生成 | 1-2 个 | Entity 由数据库驱动,但 DTO 和业务层仍需手动 |
每个方案里,文件数最少也是 2 个。原因在于,“数据定义”和“数据传输”长期被当作两件独立的事来处理。
但仔细想想,对于一张只做增删改查的表来说,你定义 UserEntity 和 UserDTO 时,90% 的字段其实是重复的。你等于在维护双份信息。
变更成本 = 文件数 × 耦合度。
文件越多,耦合越分散,AI 就越难帮上忙。因为 AI 不理解“你改 Entity 的时候应该同步改 DTO 吗?”——它不清楚你的项目约定,它只看到当前打开的这个文件。
三、如果一张表只有一个文件
现在回到同一个需求,看看如果一张表只对应一个文件会怎样:
复制代码// UserService.java —— 一个表只写这一个类
public class UserService {
// 查一个
public User getById(Long id) {
return DB.Pojo.select(User.class).eq("id", id).queryBean();
} // 查列表
public Page list(String keyword) {
return DB.Pojo.select(User.class)
.like("name", keyword)
.page(1, 20)
.queryBeanPage();
} // 增
public User add(User user) {
return DB.Pojo.insert(user);
} // 改
public User modify(Long id, User user) {
return DB.Pojo.updateById(User.class, id);
}
}
现在加 remark 字段,流程就变成了:
- 数据库加一列:
ALTER TABLE user ADD COLUMN remark VARCHAR(255); user表对应的这个类——什么都不用改。
原因很简单:DB.Pojo.select(User.class) 自动从数据库表结构拿到列信息,DB.Pojo.insert(user) 把 JSON 里的 remark 字段自动映射到数据库列。没有 Entity 要改,没有 DTO 要同步,没有 Mapper.xml 要检查。
变更面从 6 个文件压缩到 1 个文件。当 AI 在这个基础上来帮你改代码时,错误率就会从“大概率漏改”直接降到“基本不出错”。
四、压力测试:同一个需求,不同方案要改几个地方
| 操作 | MyBatis-Plus | JPA | 此方案 |
|---|---|---|---|
| 加一个字段 | Entity + DTO + Mapper.xml + ServiceImpl + 前端DTO ≈ 5 处 | Entity + DTO + @Query检查 ≈ 3 处 | 数据库 1 处(框架自动映射) |
| 改字段类型 | 同上 5 处 | 同上 3 处 | 数据库 1 处 |
| 加一个查询条件 | Mapper.java + Mapper.xml + ServiceImpl ≈ 3 处 | Repository + Service ≈ 2 处 | 改 Service 的方法参数即可 |
| 新增一张表 | 生成 4-6 个文件 | 生成 2-3 个文件 | 1 个文件 |
这里比的不是“谁的代码写得更短”,而是“加一个字段,要改几个地方”。因为工作中,不是每天都需要加新表,但可能每天都在被产品经理要求加字段。
五、为什么文件少会让 AI 的准确率翻倍
这其实很容易理解,不是什么复杂的推测。
当你让 AI 改一个字段时,它需要同时理解 Entity、DTO、Mapper.xml、ServiceImpl 这四个文件的上下文。上下文越长,AI 的注意力越分散,漏改的概率就越高。
而当你只有一个 UserService.java 时,上下文是高度内聚的。AI 在这个文件里改代码,它不需要跨文件猜测影响范围。
少文件 = 少上下文 = 少出错。这已经不只是代码风格问题了,这是 AI 辅助编程时代里一个实实在在的工程成本问题。
换句话说:你项目的文件结构,正在直接决定 AI 帮你写代码的质量上限。
六、AI 生成 480 个文件 vs AI 用此方案管理 80 个文件
做一个最终的对比:
复制代码项目规模:80 张表的业务系统
MyBatis-Plus + AI:
生成 480 个文件(80表 × 6文件)
加一个字段平均改 5 个文件
AI 漏改概率:你每次都要人工检查 4-5 个文件
此方案:
维护 80 个 Service 文件(80表 × 1文件)
加一个字段:数据库 1 处
AI 漏改概率:一个文件前后一读就看清了
这里的关键差距不是 480 个文件和 80 个文件代码量的区别。而是变更时你需要排查 5 个文件还是 1 个文件的区别。而这个差距在 AI 写代码的时代被放大了——文件越多,AI 越容易漏改,你越需要花时间去人工做校验。
七、什么时候这样不行
当然,这个方案并不是万能的。
它的边界很清楚:
-
标准 CRUD 表:80% 以上的业务表只做增删改查,单文件方案最合适
-
单表查询为主:按 ID 查、按条件查、分页查,这类需求很常见
-
字段和数据库列一一对应:不需要复杂的映射转换,这种场景下效率最高
-
复杂多表关联 + 聚合查询:该写 SQL 还是要写,该建专门的查询 Service 也必须建
-
需要和第三方 API 做字段转换:DTO 层的存在依然有意义,不能为了省文件而硬省
-
对缓存、事务有复杂编排的业务:单文件只负责数据访问,业务编排逻辑另起一个 Service 来处理
这里的“单文件”省的是重复定义,而不是业务编排。你仍然可以有 OrderBizService 来编排订单流转逻辑——它不需要再对应一个 OrderMapper.java + OrderMapper.xml。
八、如果只记一句话
下次你用 AI 写 CRUD 的时候,别只盯着它生成代码有多快。数一数它一口气生成了几个文件。文件数就是你下一次产品改需求时,需要人工排查的范围。
