AI 时代持久层开发的动态最优解:从 7:2:1 到 5:3:2,约束强度决定一切

📅 2026/7/12 7:42:28 👁️ 阅读次数 📝 编程学习
AI 时代持久层开发的动态最优解:从 7:2:1 到 5:3:2,约束强度决定一切

AI 时代持久层开发的动态最优解:从 7:2:1 到 5:3:2,约束强度决定一切

为什么 SimpleDAO 能防止 AI 生成 MyBatis 屎山代码?

摘要

AI 能写代码,但写不出好架构。本文提出 AI 时代持久层开发的“动态比例模型”——AI 与代码生成器是互补关系,不是替代关系,更不是对立关系。

  • 传统代码生成器:承担50%~80%的确定性工作(表 → 代码的精确映射)
  • AI:承担15%~30%的不确定性辅助(设计建议、性能分析、Bug 定位)
  • :聚焦5%~30%的核心决策(架构、业务规则、最终把关)

比例不是固定的。它随工程规范约束强度、场景复杂度、人的控制能力动态调整。

基于Spring JDBC Ultra(SimpleDAO)的 SQL-First 范式,我们证明:防止 AI 写出屎山代码的唯一方法,是在范式层面做减法——将 AI 的"创造性"约束在可控范围内,而不是在代码层面做事后审查。

AI 万能论是片面的,AI 的代价是高昂的。

一、AI 写代码的"三重幻觉"与三重真实成本

幻觉 1:AI 写得快 = 效率高

场景:从数据库表生成一套完整 CRUD(Entity + DAO + Service + Controller + 前端 + 测试) AI(GPT-4)路径: 写 Prompt(描述表结构 + 生成规则) 2 分钟 等待生成 15 秒 检查输出,发现字段映射错误 3 分钟 写修正 Prompt 1 分钟 再次生成 15 秒 发现 Swagger 注解遗漏 2 分钟 发现前端控件类型不匹配 2 分钟 第三轮交互... ... 总计:10-15 分钟,Token 消耗数千 传统生成器(SimpleDAO)路径: 配置数据源 30 秒 选择表 + 选择模板 10 秒 点击生成 < 1 秒 总计:< 1 分钟,0 Token 消耗

AI 的单轮生成快,但"达到可用状态"的总时间更长、成本更高。

幻觉 2:AI 写得对 = 确定性高

维度传统生成器AI
相同输入,相同输出✅ 100% 可重复❌ 温度参数导致变异
字段名拼写一致性✅ 模板保证❌ 可能驼峰/下划线混用
注解完整性✅ 规则驱动❌ 可能遗漏 @Schema
前端控件类型匹配✅ 类型映射表❌ 可能把 Integer 映射成 Text
代码风格一致性✅ 模板统一❌ 受 Prompt 描述影响

AI 的"创造性"在工程化场景中是负债,不是资产。

幻觉 3:AI 能替代传统代码生成器

这是最大的幻觉。AI 和生成器不是替代关系,是互补关系。它们解决的是完全不同的问题:

AI 的舒适区:不确定性 · "帮我设计一个支持分库分表的订单系统" · "这个慢查询怎么优化?" · "这段代码有什么并发问题?" 生成器的舒适区:确定性 · "表结构已定,生成全套 CRUD" · "字段类型已定,生成前端表单" · "API 路径已定,生成 Swagger 文档"

AI 的三重真实成本

成本类型说明量化
训练成本AI 需要理解框架的私有语法(XML、OGNL、Criteria API)每个框架需数千 Token 上下文
生成成本每次推理消耗 Token,复杂场景需多轮交互单次 500-5000 Token
持续交互成本发现错误 → 修正 Prompt → 重新生成 → 再检查时间成本 5-10 倍于生成器

SimpleDAO 的 SQL-First 范式将三重成本压缩到常数级:

  • 训练成本 ≈ 0(SQL 是 AI 原生语言,无需学习私有语法)
  • 生成成本 ≈ 0(生成器本地执行,零 Token)
  • 持续交互成本 ≈ 0(输出即最终代码,无需修正)

AI 万能论的支持者只看到了 AI 的"生成速度",忽略了 AI 的"三座成本大山"。

二、动态比例模型:约束强度决定一切

2.1 核心公式

比例不是固定的,是约束强度的函数: ┌─────────────────────────────────────────┐ │ 约束强度维度 │ │ · 工程规范文档的完备度 │ │ · 代码审查流程的严格度 │ │ · 测试覆盖率要求 │ │ · 审计合规要求 │ │ · 团队技术成熟度 │ │ · 场景复杂度(单表 CRUD → 13 表联查) │ │ · 人的控制能力(架构经验、业务理解) │ ├─────────────────────────────────────────┤ │ 动态比例公式 │ │ │ │ 生成器% = 80 - 约束强度系数 × 30 │ │ AI% = 15 + 约束强度系数 × 10 │ │ 人% = 5 + 约束强度系数 × 20 │ │ │ │ 约束强度系数:0(极松)~ 1(极严) │ └─────────────────────────────────────────┘

2.2 典型场景对照

团队类型约束强度比例(生成器:AI:人)原因
个人开发者/原型项目0.177:16:7几乎无规范,生成器大包大揽
创业公司 MVP0.371:18:11有基本规范,灵活优先
中型互联网公司0.565:20:15有代码规范,有审查流程
金融/医疗企业0.856:23:21强合规要求,人主导决策
国企/央企核心系统0.953:24:23规范极严,文档驱动

2.3 场景复杂度 × 约束强度的二维矩阵

场景复杂度 低(单表CRUD) 高(13表联查报表) ┌─────────────────┬─────────────────┐ 高约束 │ 6:3:1 │ 4:3:3 │ (金融) │ 生成器做骨架 │ 人主导设计 │ │ 人适配规范 │ AI辅助SQL │ │ AI检查合规 │ 生成器实现 │ 约束强度 ├─────────────────┼─────────────────┤ 低约束 │ 8:1:1 │ 6:2:2 │ (创业) │ 几乎全自动 │ 生成器出骨架 │ │ 人只做确认 │ AI辅助复杂SQL │ │ │ 人确认优化 │ └─────────────────┴─────────────────┘

三、SimpleDAO 生成器的"确定性 70%"包含什么?

以一张cha_channel渠道表为例,生成器 5 秒内输出11 个文件

文件内容扩展点设计
Channel.javaEntity + @Table + @Id + @Schema@Exclude 标记非持久化字段
ChannelCond.java条件类 + addCondition()注释预留 notIn/自定义条件
ChannelDao.java空类继承 BaseDao注释预留联表 SQL 模板
ChannelService.java标准 CRUD + 导入导出注释预留复杂业务方法
ChannelController.javaREST API + Swagger 注解注释预留唯一性校验
ChannelVO.java继承 Channel 的空类联表时添加扩展字段
ChannelExcel.javaExcel 导出专用 VO独立控制列宽/列序/敏感字段
MockMvcTestChannel.java接口测试模板方法级开关,按需启用
ChannelDialog.vue新增/编辑对话框dialogMix mixin 封装标准行为
ChannelList.vue不分页列表页pageMix mixin 封装标准交互
ChannelPage.vue分页列表页完整分页 + 条件折叠 + 批量操作

11 个文件,100% 确定性输出,0 Token 成本,< 1 秒完成。

扩展点设计哲学:注释即文档,取消注释即扩展

// ChannelCond.java:注释预留的扩展条件@OverrideprotectedvoidaddCondition(){and("status =",status);in("channel_id",channelIds);/* 自定义条件↓ */// notIn("channel_id", channelIdsNot); // ← 需要时取消注释// add("AND create_time >= ?", startTime); // ← 需要时添加}

四、AI 的"不确定性 20%":应该做什么?

AI 不做"生成"——生成是生成器的事。AI 做"建议"——建议是人做决策的依据。

场景 1:联表 SQL 设计辅助

// 生成器输出:单表 DAO(注释预留联表扩展)@RepositorypublicclassChannelDaoextendsBaseDao<Channel>{// private final static String SQL = "...";}// 人的输入:"渠道表需要关联用户表查创建人姓名,关联部门表查部门名称"// AI 辅助生成:privatefinalstaticStringSQL=""" SELECT t.*, u.name creator_name, d.dept_name FROM cha_channel t LEFT JOIN sys_user u ON t.create_by = u.user_id LEFT JOIN sys_dept d ON u.dept_id = d.dept_id """;// 人的确认:字段名正确?索引存在?性能可接受?

场景 2:复杂条件逻辑设计

// 生成器输出:标准条件@OverrideprotectedvoidaddCondition(){and("status =",status);and("channel_code LIKE",channelCode,3);}// 人的输入:"需要查某个时间范围内、特定省份、且状态为已审核的渠道"// AI 辅助建议:add("AND create_time >= ?",startTime);add("AND create_time <= ?",endTime);add("AND province_code IN ",provinceCodes);and("status =",(byte)2);// 已审核状态// 人的确认:业务语义正确?参数命名规范?

场景 3:性能优化与 Bug 定位

// 人写的 SQL:SELECTt.*FROMcha_channel tWHEREt.province_code=?ANDt.status=?// AI 审查建议:"province_code 和 status 的联合索引可能缺失, 建议:CREATEINDEXidx_province_statusONcha_channel(province_code,status);预估查询性能提升:从200ms 降至5ms"// 人的决策:是否创建索引?是否有写入性能影响?

AI 不做"生成",做"建议";人做"确认"与"决策"。

五、人的"核心 10%":不可替代的决策

5.1 架构选型决策

AI 建议:"可以用 JPA 的 @ManyToOne 关联" 生成器默认:单表 CRUD 人的决策: · 这个场景是否需要联表?→ 是/否 · 联表频率高吗?→ 高则生成器预留 SQL,低则手写 · 性能要求?→ 高则原生 SQL,低则框架封装 · 团队能力?→ 强则 SQL-First,弱则 ORM 兜底

5.2 业务规则确认

// AI 生成的校验逻辑:if(channelCode.startsWith("CH")){...}// 人的确认:"渠道编号必须以 'CH' 开头"是业务规则还是技术约束? → 业务规则:写入Service层校验,需产品确认 → 技术约束:写入数据库CHECK约束,需DBA确认

5.3 性能基线设定

AI 说:"这个查询 100ms 算快" 生成器不 care 性能,只保证正确性 人的决策: · 接口 SLA 是多少?→ 50ms / 100ms / 500ms? · 数据量预期?→ 万级 / 百万级 / 亿级? · 是否需要缓存?→ Redis / 本地缓存 / 不缓存? · 分库分表策略?→ 现在做 / 预留扩展 / 不做

AI 负责算出"怎么走最快",生成器负责"把路修好",而只有你知道"这条路通往哪里,以及该不该修"。

技术决策权,从来没有、也永远不会从人手里滑落。

六、防止 AI 屎山:范式层面的减法,不是代码层面的审查

传统做法的困境:AI 生成 → 人审查 → 改 AI 的代码

AI 生成 MyBatis XML(500 行) ↓ 人审查发现 10 个问题(ResultMap 错误、OGNL 语法、标签嵌套...) ↓ 改完 10 个问题,引入 3 个新问题(标签未闭合、别名冲突...) ↓ 循环往复... ↓ 结果:屎山代码,技术债务爆炸,审查成本 > 重写成本

SimpleDAO 做法:范式约束 → AI 在约束内发挥

前提:SQL-First 范式已定义 · 单表:继承 BaseDao<T>,零代码 · 联表:写原生 SQL,page/list/field/row 统一 API · 条件:BaseCondition.add() 方法族,不分单表联表 · 结果:BeanPropertyRowMapper 自动映射 · 禁止:XML、OGNL、Criteria API、JPQL、DSL AI 在约束内工作: · 不会生成 XML(范式禁止) · 不会生成 Criteria API(范式禁止) · 不会生成 JPQL(范式禁止) · 不会生成 JOOQ DSL(范式禁止) · 只能生成:SQL 字符串 + Java 方法调用 结果:AI 的"创造性"被范式约束在可控范围内 输出即最终代码,无需审查修正

防止 AI 写出屎山代码的唯一方法:不是事后审查 AI 的输出,是事前限制 AI 的输入空间。

七、SimpleDAO 在 AI 时代的三重成本优势

7.1 训练成本:压缩到零

框架AI 需要学习的上下文Token 消耗
MyBatisXML 结构 + OGNL 表达式 + ResultMap 语法 + 拦截器机制5000+
JPAEntity 注解 + Criteria API + JPQL 语法 + Session 机制4000+
JOOQDSL API + 代码生成器配置 + 类型系统6000+
SimpleDAOSQL 语法(AI 已内置)+ 3 个方法(add/and/in)< 500

SimpleDAO 的训练成本趋近于零,因为 SQL 是 AI 的"母语"。

7.2 生成成本:本地执行,零 Token

MyBatis + AI: 生成 Entity(500 Token) 生成 Mapper XML(1500 Token) 生成 Service(800 Token) 生成 Controller(800 Token) 总计:3600 Token SimpleDAO + 生成器: 11 个文件,本地 Freemarker 模板替换 总计:0 Token,< 1 秒

7.3 持续交互成本:指数级下降

MyBatis + AI: 第一轮:生成 XML(3000 Token) 发现问题:ResultMap 字段映射错误 第二轮:修正 XML(3000 Token) 发现问题:OGNL 表达式语法错误 第三轮:修正 OGNL(3000 Token) 发现问题:association 标签嵌套错误 ... 总计:9000+ Token,3+ 轮交互,20+ 分钟 SimpleDAO + AI: 第一轮:生成 SQL 字符串(500 Token) 发现问题:字段别名错误 第二轮:修正 SQL(500 Token) 确认无误 总计:1000 Token,2 轮交互,3 分钟

人与 AI 的持续交互成本,SimpleDAO 是 MyBatis 的 1/5 ~ 1/10。

八、动态比例的实践路径

路径一:低约束团队(创业/原型)→ 7:2:1 起步

步骤 1:生成器 5 秒出全套代码(70%) 步骤 2:AI 辅助复杂 SQL 设计(20%) 步骤 3:人确认业务规则 + 性能基线(10%) 目标:1 天搭出可运行的管理系统

路径二:中约束团队(成长型公司)→ 逐步推向 6:3:1

步骤 1:基于生成器代码,补充团队规范 步骤 2:AI 辅助代码审查,确保规范合规 步骤 3:人主导架构决策,生成器 + AI 执行 目标:规范与效率的平衡

路径三:高约束团队(金融/医疗)→ 5:3:2 深耕

步骤 1:人制定详细规范文档(50%) 步骤 2:基于规范定制生成器模板(30%) 步骤 3:AI 辅助规范检查 + 复杂场景设计(20%) 目标:合规优先,效率不落后

九、结语:范式即约束,约束即自由

“AI 特别有用,但它不应该抢传统代码生成器的活。”

这不是保守,这是工程理性

  • 生成器做确定性映射(表 → 代码),零成本、100% 正确、可重复
  • AI 做不确定性探索(设计建议、Bug 定位),高价值、需验证、辅助决策
  • 人做不可替代决策(架构、规则、责任),核心、最终把关、承担后果

SimpleDAO 的 SQL-First 范式,为 AI 时代提供了一个"约束框架":

  • 不是限制 AI 的能力,是限制 AI 的"犯错空间"
  • 不是替代人的决策,是释放人的创造力
  • 不是否定其他框架,是证明"简单可以更有力量"

动态比例的核心洞察:

约束强度决定分工比例,场景复杂度决定交互深度,人的控制能力决定最终质量。

在这个范式下:

  • AI 不会生成 XML 屎山,因为范式禁止 XML
  • AI 不会生成 Criteria API 灾难,因为范式禁止 Criteria
  • AI 不会生成 JOOQ DSL 迷宫,因为范式禁止 DSL
  • AI只能生成 SQL 字符串 + Java 方法调用——这是 AI 最擅长、人最容易审查、数据库最直接执行的形式

7:2:1 或 5:3:2,不是选择,是结果。选择 SimpleDAO,选择让 AI 在正确的边界内发挥。

AI 万能论是片面的——它看到了 AI 的"可能性",却忽略了 AI 的"不可控性"和"高昂的持续成本"。

生成器 + AI + 人 = 工程理性的三角结构,缺一不可。

参考与试用

  1. 核心框架源码:https://gitee.com/gao_zhenzhong/simple-dao
  2. 系统底座:https://gitee.com/gao_zhenzhong/simple-dao-starter
  3. 代码生成器:https://gitee.com/gao_zhenzhong/simple-dao-coder
  4. 实战案例:https://gitee.com/gao_zhenzhong/simple-dao-demo