当我不想手写190个Java文件时,我让Python帮我写代码
问题的开始
这学期的课设项目是一个"铁路客运站设备运维配置管理系统"。老师的要求很明确:后台用 Spring Boot,要有完整的 CRUD 接口,前端用 React。
我打开需求文档一看,好家伙——19个业务模块:
车站管理、网格管理、位置管理、设备分类、设备用途、巡检线路、巡检项目、保养线路、保养项目、检测线路、检测项目、故障字典、备件库位、备件分类、备件型号、设备厂商、键值字典、流程定义、流程路由……
每个模块在 Spring Boot 里需要至少 5 个文件:
- Entity(实体类)
- Mapper(数据访问接口)
- Service 接口
- ServiceImpl(服务实现)
- Controller(控制器)
19 × 5 = 95个Java文件。这还不算前端页面,前端每个模块还要写一个 React 页面组件,又是 19 个文件。
我当时就坐不住了。
不是我懒,是这件事不值得手动做
仔细看了一下这些文件的结构,我发现一个惊人的事实——它们几乎一模一样。
所有的 Entity 都是 @Data + @TableName + 一个 Long id + 几个通用字段(createTime、updateTime、createBy、updateBy、deleted)。
所有的 Mapper 都是 extends BaseMapper<Xxx>。
所有的 Service 都是 extends IService<Xxx>。
所有的 ServiceImpl 都是 extends ServiceImpl<XxxMapper, Xxx> implements IXxxService。
所有的 Controller 都是四个接口:list()、getById()、save()、delete()。
这不就是模板填空吗?
让 Python 干苦力活
我花了半小时写了一个 Python 脚本——generator.py。核心思路很简单:
- 把 19 个模块的信息存成一个列表,每个元素是
(类名, 表名, 中文注释) - 用 Python 的 f-string 拼出 Java 代码模板
- 循环生成所有文件,写入对应的目录
entities = [("Station", "sys_station", "车站"),("Grid", "sys_grid", "网格"),("Location", "sys_location", "位置"),# ... 共19个
]for name, table, comment in entities:make_entity(name, table, comment) # Entity.javamake_mapper(name, comment) # XxxMapper.javamake_service(name, comment) # IXxxService.javamake_service_impl(name, comment) # XxxServiceImpl.javamake_controller(name, comment) # XxxController.java
每个 make_xxx 函数就是一个带参数的字符串模板。比如 make_entity:
def make_entity(name, table, comment):content = f"""package {base_pkg}.entity;import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;/*** {comment}实体类*/
@Data
@TableName("{table}")
public class {name} {{@TableId(type = IdType.AUTO)private Long id;private String name;@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;@TableField(fill = FieldFill.INSERT)private String createBy;@TableField(fill = FieldFill.INSERT_UPDATE)private String updateBy;@TableLogicprivate Integer deleted;
}}
"""with open(f"{base_dir}/entity/{name}.java", "w") as f:f.write(content)
效果
跑一遍脚本,5 秒钟,95 个 Java 文件全部生成完毕,目录结构整整齐齐:
backend/src/main/java/com/railway/equipment/
├── entity/ ← 19个实体类
├── mapper/ ← 19个Mapper接口
├── service/ ← 19个Service接口
│ └── impl/ ← 19个ServiceImpl
└── controller/ ← 19个Controller
对比一下,如果手动写:复制粘贴、改类名、改表名、改注释,一个文件大概 2 分钟,95 个就是 3 个多小时。而且中间一定会出错——类名没改全、包路径写错、注解漏掉——这些都是 Spring Boot 启动时才会报的错,找起来很折磨人。
这件事教会我什么
说实话,代码生成不是什么高深技术。模板 + 循环,大一C语言课都能写。但在此之前,我的思维方式是"要写代码了 → 打开 IDEA → 开始敲"。这次让我意识到在敲代码之前,应该先看看有没有模式可以自动化。
几个具体收获:
-
如果一件事要做三遍以上,写个脚本。 这是 Linux 哲学里的"懒惰是程序员的美德"。19 个模块显然够本了。
-
Python 是程序员的瑞士军刀。 不需要 IDE,不需要编译,写完就跑。Java 项目里穿插一个 Python 脚本做辅助工作,这在工程中非常常见。
-
代码生成 ≠ 代码质量差。 生成的代码结构统一、命名规范、不会漏注解。比手动复制粘贴可靠得多。像 MyBatis-Plus 官方就有自己的代码生成器,Spring 生态里这类工具遍地都是。
-
这个思路可以复用。 脚本放在项目里,后面如果要加新模块,改一行列表就行。甚至以后换一个类似的项目,改改模板就能接着用。
后续
这个脚本只是整个项目的起点。生成完基础代码后,我还在此基础上搭建了 FastAPI 后端(配备 AI 智能体的四层架构:感知层、决策层、执行层、记忆层)和 React 前端(配合 Ant Design 组件库和语音交互功能),最终形成了一个完整的设备运维配置管理系统。
但那就是另一个故事了。至少今天,95 个 Java 文件不用我手写,我觉得这是我本学期最值的半小时。
本项目代码开源在 GitHub,欢迎交流:railway-config-agent
