今天我们来讲一下MES的代码生成工具。
一、开发目的
在软件开发过程中,开发人员常常需要编写大量重复的代码,例如增删查改功能、树形结构展示、主子表关联操作等。对于前后端来说,还会分别涉及到如前端页面布局、后端业务逻辑处理和数据库交互等具体模块的代码编写。这些重复性的工作不仅消耗了大量时间和精力,还容易引入人为错误。
通过开发此代码生成工具,可提高开发效率,将开发人员从繁琐的重复工作中解放出来,使其能够将更多的精力投入到核心业务逻辑和创新功能的开发上。同时,借助统一的模板生成代码,还能保证代码风格的一致性,便于后期的维护和管理。
二、功能设计
2.1 功能概述
| 功能模块 | 描述 |
|---|---|
| 数据表配置 | 自动读取数据库表结构,记录表和字段的元信息 |
| 模板配置 | 支持多种模板类型(CRUD、树形、主子表),可灵活扩展 |
| 前端生成 | 生成React代码,采用Ant Design 5组件库,结构清晰,UI统一 |
| 后端生成 | 生成Spring Boot标准三层结构代码(Controller、Service、Mapper),使用MyBatis-Plus |
| 在线预览 | 在线渲染生成的代码,供开发者快速预览 |
| 文件下载 | 将完整代码压缩为ZIP文件供下载集成 |
| 自定义配置 | 可配置包路径、模块名、业务名、查询方式、表单组件等 |
| 模板引擎 | 使用 Freemarker 模板引擎进行动态代码渲染 |
2.2 数据配置
系统提供两张配置表,用于记录生成代码所需的相关信息:
- *gen_table:记录数据库表的基本信息,如生产模板类型(对应三种页面类型)、生产包路径、模块名和业务名等。
| 字段名 | 类型 | 长度 | 允许空 | 默认值 | 注释 |
|---|---|---|---|---|---|
| table_id | INT | - | NO | AUTO_INCREMENT | 编号 |
| table_name | VARCHAR | 200 | YES | NULL | 表名称 |
| table_comment | VARCHAR | 500 | YES | NULL | 表描述 |
| class_name | VARCHAR | 100 | YES | NULL | 实体类名称 |
| tpl_category | VARCHAR | 200 | YES | 'crud' | 使用的模板(crud单表操作 tree树表操作) |
| package_name | VARCHAR | 100 | YES | NULL | 生成包路径 |
| module_name | VARCHAR | 30 | YES | NULL | 生成模块名 |
| business_name | VARCHAR | 30 | YES | NULL | 生成业务名 |
| function_name | VARCHAR | 50 | YES | NULL | 生成功能名 |
| function_author | VARCHAR | 50 | YES | NULL | 生成功能作者 |
| gen_type | CHAR | 1 | YES | '0' | 生成代码方式(0zip压缩包 1自定义路径) |
| gen_path | VARCHAR | 200 | YES | '/' | 生成路径(不填默认项目路径) |
| parent_table_name | VARCHAR | 64 | YES | NULL | 父表名称 |
| sub_table_fk_name | VARCHAR | 64 | YES | NULL | 子表关联的外键名 |
| remark | VARCHAR | 500 | YES | NULL | 备注 |
| tree_code | VARCHAR | 255 | YES | NULL | 树编码字段 |
| tree_name | VARCHAR | 255 | YES | NULL | 树名称字段 |
| tree_parent_code | VARCHAR | 255 | YES | NULL | 树父编码字段 |
| parent_menu_id | BIGINT | - | YES | NULL | 上级菜单ID字段 |
| parent_menu_name | VARCHAR | 255 | YES | NULL | 上级菜单名称字段 |
| parent_table_pk | VARCHAR | 255 | YES | NULL | 关联父表主键 |
| options | VARCHAR | 1000 | YES | NULL | 其它生成选项 |
| create_by | VARCHAR | 64 | YES | NULL | 创建者 |
| create_time | DATETIME | - | YES | NULL | 创建时间 |
| update_by | VARCHAR | 64 | YES | NULL | 更新者 |
| update_time | DATETIME | - | YES | NULL | 更新时间 |
- gen_table_column:记录数据库表的字段信息,包括列表是否显示、是否作为查询字段、查询方式(如等于、模糊匹配等)、使用组件(如输入框、下拉框等)和使用字段等。
| 字段名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| column_id | INT | 编号(主键,自增) | |
| table_id | VARCHAR(64) | 归属表编号 | |
| column_name | VARCHAR(200) | 列名称 | |
| column_comment | VARCHAR(500) | 列描述 | |
| column_type | VARCHAR(100) | 列类型(数据库字段类型,如 varchar(255)) | |
| java_type | VARCHAR(500) | JAVA类型 | |
| ts_type | VARCHAR(255) | TypeScript类型 | |
| java_field | VARCHAR(200) | JAVA字段名 | |
| is_pk | TINYINT | 是否主键(1是) | |
| is_increment | TINYINT | 是否自增(1是) | |
| is_required | TINYINT | 是否必填(1是) | |
| is_insert | TINYINT | 是否为插入字段(1是) | |
| is_edit | TINYINT | 是否编辑字段(1是) | |
| is_list | TINYINT | 是否列表字段(1是) | |
| is_query | TINYINT | 是否查询字段(1是) | |
| query_type | VARCHAR(200) | 'EQ' | 查询方式(等于、不等于、大于、小于、范围) |
| html_type | VARCHAR(200) | 显示类型(文本框、文本域、下拉框等) | |
| dict_type | VARCHAR(200) | 字典类型 | |
| sort | INT | 排序 | |
| create_by | VARCHAR(64) | 创建者 | |
| create_time | DATETIME | 创建时间 | |
| update_by | VARCHAR(64) | 更新者 | |
| update_time | DATETIME | 更新时间 |
三、代码实现
3.1 Freemarker 模板
本工具使用 Freemarker 作为模板引擎来生成代码。Freemarker 是一个强大的模板引擎,它允许开发人员定义代码模板,并根据数据动态填充模板,生成最终的代码文件。针对不同的代码类型(前端页面、后端 Controller、Service 和 Mapper 等)和页面类型(增删查改页面、树形页面、主子表页面),分别定义相应的 Freemarker 模板文件。 例如: 对于前端增删查改页面的列表部分,可定义如下模板:
//代码片段
<#-- 表格列定义 -->const columns: ColumnsType<${ClassName}> = [
<#list columns as column>
<#if column.isList()>
{
title: "${column.columnComment}",
width: 120,
key: "${column.javaField}",
dataIndex: "${column.javaField}",
<#if column.dictType?? && column.dictType != "">
render: (_, record) => (
<TableDictTag dictCode="${column.dictType}" value={record.${column.javaField} ?? ''}/>
)
</#if>
},
</#if>
</#list>{
title: "操作",
fixed: 'right',
key: "operation",
align: "center",
width: 100,
render: (_, record) => (
<Space>
<Button type="link" onClick={() => handleView(record)}>
{t("common.view")}
</Button>
<Button type="link" onClick={() => handleEdit(record)}>
{t("common.edit")}
</Button>
</Space>
),
},
];
备注: 如需查看Freemarker每个文件的生成模板请下载源码, 模板目录:hgyc-generator/src/main/resources/templates
3.2 代码生成流程
- 表导入:设计完数据库表之后,在功能页面导入数据库表
- 信息设置:在功能界面填写自定义生成信息
- 数据准备:从
gen_table和gen_table_column配置表中读取数据库表结构信息和字段配置信息。 - 模板加载:根据生产模板类型,加载相应的 Freemarker 模板文件。
- 数据填充:将从配置表中读取的信息填充到模板文件中,生成具体的代码内容。
- 代码生成:根据生成方式(在线查看或文件下载),将生成的代码展示给开发人员或保存为文件。
3.3 生成方式
- 在线查看:开发人员在工具界面选择相应的数据库表和生成选项后,系统会实时生成代码并在页面上展示,方便开发人员快速查看和调试。
- 文件下载:工具会将生成的代码保存为文件(如
.tsx、xml、ts、.java等),并提供下载链接,开发人员可以将文件下载到本地,直接集成到项目中。
四、页面类型说明
3.1 增删查改页面(CRUD)
- 适用场景:标准数据管理模块。
- 功能特性:
- 支持分页查询
- 查询条件配置化(支持等值、模糊、范围)
- 表格列展示自定义
- 表单支持校验与组件类型自定义(输入框、下拉框、日期选择等)
- 支持批量删除
3.2 树形页面
- 适用场景:组织结构、分类目录等层级关系数据。
- 功能特性:
- 树形结构展示(父子节点)
- 节点操作(新增、修改、删除)
- 与CRUD功能结合,支持树选中节点后展示其子项列表
3.3 主子表页面
- 适用场景:如订单-订单项、表单-明细项等结构。
- 功能特性:
- 主表列表展示与编辑
- 子表数据在主表内联展示与编辑
- 支持嵌套提交与事务一致性处理
四、功能说明
4.1 数据库表导入
点击功能按钮,选择要导入的数据库,如果数据库发生修改,可以点击操作列【同步】按钮把最新的数据库表结构同步。
数据库表会以表创建时间倒序显示,已导入的表不显示。
4.2 自定义生成信息
数据库表导入后,选择要修改的表,点击操作栏【编辑】按钮, 表信息分为三个tab页签:基础信息、字段信息、生成信息
- 基础信息
2. 生成信息
其中:生成模板分别有:单表、树表、父表、子表四种类型,分别对应 第四点的页面类型说明。
- 选择类型”树表“,需要填写树关联信息,如下:
- 选择类型”主表“,如果有子表信息,会显示出来,如下:
- 选择类型”子表“,需要填写子表关联信息,如下:
- 字段信息
可以自定义前端页面Form表单的组件类型,如果是字段是字典,可以选择对应的字典,字典功能请查看往期功能介绍-字典管理。
4.3 代码生产
代码生成有两种方式,这里以”在线预览“进行说明: 点击列表操作列【预览】按钮:
| 文件 | 描述 |
|---|---|
entity.java | 表结构转成的Java实体类 |
param.java | 列表查询对应的查询条件类,其中包括分页字段 |
vo.java | 只有主子表的主表才会生成,其中包括主表字段和子表数据 |
service.java | 后端业务接口类,包含增删查改、导入导出接口 |
mapper.java | mybatis mapper接口类 |
| serviceImpl.java | 后端业务接口实现类 |
| controller.java | 后端提供的接口controller,其中包含增删查改、导入导出接口 |
| mapper.xml | mybatis 自定义sql的xml文件 |
| entity.d.ts | 前端Typescript 的表类型定义 |
| sql | 菜单生成的sql语句 |
| api.ts | 前端请求后端接口的方法 |
| index.tsx | 前端页面代码,分别对应不同类型的模板会生成不同的代码 |
五、总结
本代码生成工具通过提供统一的代码生成解决方案,大大提高了开发效率,降低了开发成本。同时,其支持的多种页面类型和灵活的配置方式,能够满足不同项目的需求。在使用过程中,开发人员只需根据业务需求配置好数据库表和字段信息,即可快速生成高质量的前后端代码,有效减少了重复劳动,提升了项目的开发质量和可维护性。
本文源码已上传Gitee 开源项目地址:
欢迎在评论区分享你的技术选型经验,或对本文方案的改进建议!
关注公众号「慧工云创」