news 2026/4/8 18:05:21

拒绝 CRUD 搬砖:我如何用脚本 + 模板把重复工作降到 10%

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
拒绝 CRUD 搬砖:我如何用脚本 + 模板把重复工作降到 10%

一、真实痛点引入:我们是工程师,还是“高级打字员”?

回想一下你最近接的一个需求:“给后台增加一个商品分类管理功能”。

逻辑极其简单:增删改查(CRUD)。但你需要做哪些动作?

  1. 设计 MySQL 表结构create table...
  2. 在 Java/Go 代码里定义实体类Struct/POJO
  3. 写 DAO 层(Mapper/Repository),写 SQL。
  4. 写 Service 层,把 DAO 调一遍。
  5. 写 Controller 层,定义 Request/Response DTO,做参数校验。
  6. 注册路由,写 API 文档…

这套流程走下来,至少 2 小时。其中1 小时 50 分钟在机械地复制粘贴、修改变量名,只有 10 分钟在思考“分类能不能重复”、“删除时有没有级联逻辑”。

这种工作不是在写代码,是在消耗生命。作为 1-5 年经验的开发者,如果你的核心竞争力还停留在“我 CRUD 写得快”,那么 35 岁危机离你真的很近。

今天,我将把架构师团队内部使用的**“代码生成方法论”**开源出来。不依赖任何重型框架,用最简单的 Python 脚本 + Jinja2 模板,教你搭建一套属于自己的“效率引擎”。


二、核心问题拆解:从“复制粘贴”到“Schema 驱动”

解决重复工作的进化路径通常有三层:

  1. 石器时代(CV 大法):打开旧代码 -> 复制 -> 粘贴 -> 全局替换“User”为“Product”。
  • 缺点:容易漏改,容易把 bug 复制过去,极其枯燥。
  1. 铁器时代(IDE Snippets):配置soutpsvm等快捷键。
  • 缺点:只能解决行级重复,解决不了文件级、模块级的重复。
  1. 工业时代(Schema Driven Dev):定义一份元数据(Schema),让机器自动生成所有分层代码。

我们的目标是第 3 层。核心难点在于:如何设计一个“万能模具”,既能生成代码,又不覆盖我后续手写的自定义逻辑?


三、原理图解:自动代码生成流水线

我们要构建一个轻量级的流水线,输入是“表结构”或“定义文件”,输出是“可运行的代码”。

提取元数据

继承/隔离

人工扩展

输入源: SQL DDL / JSON Schema

解析器 Parser

中间上下文 Context

注: 含类名/字段/类型/注释

渲染引擎 Jinja2

模板: Controller

模板: Service

模板: DAO/Mapper

生成: ProductController

生成: ProductMapper.xml

生成: ProductService

BaseService 机器生成

ServiceImpl 人工手写

架构设计重点:注意右下角的“隔离策略”。成熟的生成器绝不能直接覆盖用户写代码的文件。通常采用Base 类(生成) + Impl 类(继承/组合,手写)的模式,或者Hook 模式


四、核心代码实现:Python + Jinja2 实战

这里以Go 语言 Web 开发为例(Java/Python 同理),演示如何通过一个 YAML 配置文件,自动生成 Struct、Repository 和 Service。

1. 准备工作

安装 Python 依赖:
pip install jinja2 pyyaml

2. 定义元数据 (product.yaml)

这是我们唯一需要手写的东西,描述业务模型。

model:name:"Product"table_name:"t_product"comment:"商品信息表"fields:-name:"ID"type:"int64"json:"id"db:"id"comment:"主键"-name:"Name"type:"string"json:"name"db:"name"comment:"商品名称"-name:"Price"type:"float64"json:"price"db:"price"comment:"价格"

3. 编写模板 (model.go.tpl)

使用 Jinja2 语法,这比任何硬编码的字符串拼接都好维护。

packagemodel// {{ model.comment }}type{{model.name}}struct{{%forfield in model.fields%}{{field.name}}{{field.type}}`gorm:"column:{{ field.db }}" json:"{{ field.json }}"`// {{ field.comment }}{%endfor%}}// TableName 映射表名func({{model.name}})TableName()string{return"{{ model.table_name }}"}

4. 编写生成脚本 (gen.py)

这是流水线的引擎。

importyamlfromjinja2importTemplateimportosdefgenerate_code(yaml_file,template_file,output_file):# 1. 读取元数据withopen(yaml_file,'r',encoding='utf-8')asf:data=yaml.safe_load(f)# 2. 读取模板withopen(template_file,'r',encoding='utf-8')asf:tpl_content=f.read()template=Template(tpl_content)# 3. 渲染# 这里可以注入一些辅助函数,比如驼峰转下划线等rendered_code=template.render(model=data['model'])# 4. 输出文件withopen(output_file,'w',encoding='utf-8')asf:f.write(rendered_code)print(f"✅ 成功生成:{output_file}")if__name__=="__main__":# 实战中这里通常会遍历整个目录generate_code('product.yaml','model.go.tpl','product.model.go')

运行结果:
执行python gen.py,你将瞬间得到一个标准规范、带注释、带 Tag 的 Go 结构体文件。


五、性能 / 稳定性 / 优化分析

虽然是生成代码,但如果不注意细节,生成的代码就是“屎山”。

关注维度潜在坑点优化方案
可维护性每次重新生成都会覆盖我手写的逻辑(例如FindByNameGap Pattern(缝隙模式):生成两个文件,gen_model.go(只读,机器生成)和model.go(手动维护,继承前者或组合前者)。脚本只覆盖gen_开头的文件。
类型映射数据库的tinyint转成 Go 是int8还是bool在解析器层建立TypeMapper 字典,统一处理 SQL 类型到编程语言类型的转换,避免硬编码。
格式化生成的代码缩进乱七八糟,Git Diff 很难看生成后自动调用gofmt(Go) 或google-java-format(Java) 或Black(Python) 进行格式化,保证代码美观。

进阶技巧:反向工程
不要手写 YAML。最高效的方式是:
DB --> SQLParser --> Context --> Code
直接连接开发库,读取information_schema,一键生成整个数据库的所有 CRUD 代码。


六、实战案例复盘:重构老旧管理后台

背景:
我们要为一个遗留系统开发一个新的运营后台,涉及 30 张表。团队只有 2 个人,工期 5 天。

传统做法:
一个人负责 15 张表,平均每张表写 Controller/Service/DAO 需要 2 小时(含联调)。
Total = 30 * 2 = 60 小时。2 个人需要不吃不喝干 4 天,最后 1 天联调,大概率延期。

Script + Template 做法:

  1. Day 1 上午:花 3 小时设计数据库表结构。
  2. Day 1 下午:编写/调整 Python 生成脚本,适配公司的 Result 包装结构和异常处理规范。
  3. Day 1 晚上:运行脚本,5 秒钟生成了 30 张表的 CRUD 基础代码(含增删改查 API、分页查询)。
  4. Day 2 - Day 4:两人专注于处理 20% 的特殊业务逻辑(如:订单状态流转、复杂的报表统计)。
  5. Day 5:测试上线。

结果:
代码风格极其统一(全是脚本生成的),Bug 率极低(模板没问题,代码就没问题),提前 1 天完工。


七、经验总结:架构师的 5 条建议

  1. Don’t Repeat Yourself (DRY):不仅是代码逻辑不重复,写代码的动作也不要重复。凡是出现第三次的机械操作,必须脚本化。
  2. 模板即规范:把团队的代码规范写进 Jinja2 模板里。新人入职,让他运行脚本生成代码,他写出来的代码就和架构师的一模一样。
  3. 生成的代码要是“可编译的”:不要生成半成品。脚本跑完,IDE 里应该没有红线,项目应该能直接启动。
  4. 慎用重量级 ORM 生成器:Hibernate 或 MyBatis Generator 往往配置繁琐且难以定制。自写 Python 脚本通常只需 100 行代码,灵活度却高十倍。
  5. 保持敬畏:自动化是手段,不是目的。对于核心复杂的业务域(Domain),依然需要你精雕细琢的手写代码,别试图生成一切。

从今天开始,试着写一个脚本,把你手头那个讨厌的 CRUD 模块生成出来。你会发现,剩下的时间用来划水摸鱼……啊不,用来学习源码,是多么香!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/11 2:29:04

【计算机毕业设计案例】基于springboot的电影院订票选座系统电影院票务预定系统(程序+文档+讲解+定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/3/28 16:15:29

2026毕设ssm+vue驴友社交管理系统论文+程序

本系统(程序源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。 系统程序文件列表 开题报告内容 一、选题背景 关于户外旅游社交问题的研究,现有研究主要以传统旅游信息平台或单一社交应用为主,专门针对驴友…

作者头像 李华
网站建设 2026/4/5 9:51:24

校直机设计

2 设计要求 (1)已知原始数据及工作条件 ① 校直机所要校直的工件,板簧规格为2590mm; ② 工作地点为室内,工作平稳; ③ 校直液压缸载荷400kN。 (2)设计成果 ① 毕业设计说明书1份&…

作者头像 李华
网站建设 2026/3/29 12:45:14

龙门射线检测装置设计

2 龙门射线检测装置总体设计方案 2.1 龙门射线检测装置简介 龙门射线检测装置可用于中小型机械设备的检测中,利用一些穿透性较强的射线进行无损探测,将探测所得图像利用图像处理技术,进一步的分析处理,获得检测报告进行反馈&#…

作者头像 李华
网站建设 2026/4/1 1:06:43

TCP/IP协议简单介绍

协议栈概述TCP/IP协议栈的基本概念和历史背景四层模型(应用层、传输层、网络层、链路层)与OSI七层模型的对比协议栈在现代网络通信中的核心作用链路层(数据链路层)链路层的主要功能和职责常见协议:以太网(E…

作者头像 李华
网站建设 2026/4/2 1:32:20

30型离心抛光机结构设计

2 抛光机整体设计方案 2.1 整机结构及功能概述 本文设计的离心抛光机(如图2.1所示)工作时主要传动为通用电机启动带动两个塔轮传递运动给小带轮,小带轮通过皮带使得大带轮转动,与大带轮同轴连接的滚筒旋转架一并同速转动&#xff…

作者头像 李华