代码生成器这个东西,做后端开发的基本都躲不开。尤其是做企业管理类系统的朋友,一天到晚就是菜单、权限、增删改查,一两个模块手写还行,业务一多,几十张表铺过来,纯手敲真的能敲到怀疑人生。我自己早期也被这种重复劳动折磨过,后来花时间把代码生成器彻底吃透了,才发现原来一周的活可以压缩到一两天。这篇就把我在实际项目里折腾若依代码生成器前后端完整流程、源码逻辑、常见坑和一些二次开发思路都整理出来,给准备入坑或者正在用但用得不太顺的朋友一份参考。
1. 代码生成器到底解决了什么痛点
先说个实在的,代码生成器不是银弹,它解决的是"标准化重复劳动"的问题,不是"业务复杂度"的问题。很多人一听到代码生成器,要么觉得高大上,要么觉得没用,其实两种极端都不对。
1.1 从传统手写模式到自动化生成的转变
传统的手写模式大概是这样的:拿到需求,设计数据库,然后开始写 Entity、写 Mapper、写 Service、写 Controller、再写前端的 Vue 页面、API 接口调用。一个模块下来,少说十来个文件。如果是单表简单业务,这些代码八九成都是模板化的——就是改改类名、改改字段名、改改注释的事。
我见过不少团队,一开始都很自信,觉得代码量不大不需要生成器。结果业务迭代到中后期,几十张表、几百个接口,光维护这些重复代码的时间成本就非常吓人。而且人写多了容易疲劳,一疲劳就容易出低级错误,比如 WHERE 条件写错字段、DTO 里漏了字段、前端列表漏绑数据这类问题。
代码生成器的核心逻辑很简单:把数据库表结构作为输入,通过模板引擎渲染出标准化的代码文件。这个过程相当于把"人肉复制改参数"变成了"脚本自动生成",一致性更好,速度也快得多。
1.2 为什么我推荐从若依代码生成器入手
市面上代码生成工具有很多,有在线的,有 IDE 插件的,有公司自研的。但我个人建议先从若依的代码生成器入手,原因有三个。
第一个原因是它完整。若依的代码生成器不单单生成后端 /mapper、/service、/controller 那套,它连 Vue 的列表页、表单页、Api 封装文件,甚至数据库菜单的 SQL 脚本都一起生成。整个链条是闭的,生成完导入就能跑。
第二个原因是它跟若依的权限体系深度绑定。如果你用的是若依框架,用它的生成器生成出来的代码天然适配 @PreAuthorize 权限注解、菜单表 sys_menu 的按钮权限标识,不用自己再去手动关联。
第三个原因是它开源且模板可改。若依的生成逻辑不是黑盒,源码就在那里,模板文件用 Velocity 写的,想调整生成结果直接改模板就行,灵活度很高。
注意:如果你用的是非若依框架,也想借鉴它的思路,那你可以把它的
GenUtils、VelocityUtils这些核心逻辑单独拆出来,套到你自己的框架里去,这部分后面我会展开聊。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 若依代码生成器的整体设计与工作流程
用之前先搞明白它是怎么跑的。我之前见过不少同事,上来就点"生成代码",生成完发现不对,又不知道怎么改,本质就是没理解它的运行流程。
2.1 核心模块与数据表设计
若依的代码生成器主要由这几块组成:
| 模块 | 作用 | 关键接口/类 |
|---|---|---|
| 表信息管理 | 读取数据库表结构,保存在 gen_table 表中 |
IGenTableService |
| 列信息管理 | 读取表的列结构,保存在 gen_table_column 表中 |
IGenTableColumnService |
| 代码生成核心 | 组合表信息、列信息和模板,渲染出代码文件 | GenUtils、VelocityUtils |
| 模板管理 | 存放 vm 模板文件,定义各类代码文件的输出格式 |
vm/java/*.vm、vm/vue/*.vm |
这里面的核心数据表是 gen_table 和 gen_table_column,前者存表名、表注释、包名、模块名、业务名、功能名等配置,后者存每一列的属性名、字段类型、 Java 类型、是否列表显示、是否表单显示、查询方式等信息。
我第一次看的时候以为这些表的数据是手动维护的,后来才发现它有一个"导入表"的功能,你选中数据库里的一张物理表,它会自动读取该表的元数据(列名、数据类型、注释、主键等),自动填充到 gen_table_column 里,你可以在此基础上再微调。
2.2 从数据库表到代码文件的完整链路
整个流程我拆解一下,大家跟着思路走一遍就通了:
- 在数据库中建好业务表,比如要做一个客户管理,你得先有
biz_customer表。 - 登录若依后台,进入"系统工具 -> 代码生成",点击"导入",选择要生成的表。
- 系统调用
selectDbTableColumnsByTableName(不同数据库方言略有差异)读取物理表的列信息,写入gen_table_column表。 - 在代码生成列表中点击"编辑",配置基本信息:包名、模块名、业务名、功能名、生成类型(哪张
Controller返回类型)、父子表,以及每列的属性(是否必填、是否列表、查询类型等)。 - 点击"生成代码",后端从
gen_table和gen_table_column读取配置,结合包名和模块名拼接出文件路径和类名。 VelocityUtils根据模板类别获取到模板列表,对每个模板进行Velocity渲染。- 渲染完成后,把所有模板文件打成
zip包返回给前端下载。
这个过程最核心的点在于模板渲染。模板里通过 $table.xxx、$column.xxx 这类占位符引用配置对象里的属性,渲染引擎把占位符替换成实际值,最终形成可运行的代码文件。
2.3 为什么选择 Velocity 作为模板引擎
刚接触若依代码生成器源码的朋友可能会问:为什么它用 Velocity
