适合人群:已理解 RuoYi 基础架构,想掌握代码生成器提升开发效率的同学
本文是《RuoYi 框架从零到一》系列第 05 篇,基于 RuoYi-Vue 4.x 版本。建议先读 02 - 项目结构与核心模块。
一、代码生成器工作原理
RuoYi 的代码生成器是提升开发效率的核心工具,可以根据数据库表结构,一键生成前后端完整 CRUD 代码:
1.1 核心流程
4 个步骤:
- 配置生成信息:从数据库导入表,配置类名、业务名、功能描述、字段类型
- 选择模板类型:单表 CRUD / 树形表 / 主子表(一对多)
- Velocity 模板渲染:读取
.vm模板文件,注入上下文变量(表信息、字段信息),生成代码 - 下载代码文件:打包成 ZIP,包含 7 个文件(Controller / Service / Mapper / Domain / Vue / API / SQL)
1.2 生成的 7 个文件
| 文件类型 | 文件名 | 作用 |
|---|---|---|
| 后端 | XxxController.java |
处理 HTTP 请求(增删改查接口) |
IXxxService.java |
业务接口定义 | |
XxxServiceImpl.java |
业务逻辑实现 | |
XxxMapper.java |
MyBatis 数据访问接口 | |
XxxMapper.xml |
MyBatis SQL 映射文件 | |
Xxx.java |
实体类(对应数据库表) | |
| 前端 | index.vue |
Vue 列表页面(表格 + 表单) |
xxx.js |
Axios API 请求封装 | |
| SQL | menu.sql |
菜单权限 SQL(可选) |
一句话记住:数据库表 → 配置生成信息 → Velocity 渲染模板 → 前后端 7 个文件。
二、Velocity 模板引擎
RuoYi 使用 Apache Velocity 作为模板引擎(类似 Thymeleaf、FreeMarker)。
2.1 核心语法
(1)变量引用
1 | $变量名 ## 直接输出(变量不存在会报错) |
示例:
1 | package com.ruoyi.${moduleName}.controller; |
生成后(假设 moduleName=system,functionName=用户管理,ClassName=SysUser):
1 | package com.ruoyi.system.controller; |
(2)条件判断
1 | #if($condition) |
示例(根据字段类型生成不同的 Java 类型):
1 | #foreach($column in $columns) |
(3)循环遍历
1 | #foreach($item in $list) |
示例(生成所有字段的 getter/setter):
1 | #foreach($column in $columns) |
(4)方法调用
1 | $table.getTableName() ## 调用 Java 方法 |
2.2 RuoYi 常用变量
代码生成时,RuoYi 会将以下变量注入到 Velocity 上下文:
表信息($table)
| 变量 | 说明 | 示例 |
|---|---|---|
$table.tableName |
数据库表名 | sys_user |
$table.className |
Java 类名(大驼峰) | SysUser |
$table.businessName |
业务名(小驼峰) | user |
$table.moduleName |
模块名 | system |
$table.functionName |
功能名称 | 用户 |
$table.functionAuthor |
作者 | ruoyi |
$table.pkColumn |
主键字段对象 | user_id |
字段信息($columns)
$columns 是一个 List<GenTableColumn>,每个元素包含:
| 变量 | 说明 | 示例 |
|---|---|---|
$column.columnName |
数据库字段名 | user_name |
$column.javaField |
Java 属性名(小驼峰) | userName |
$column.capJavaField |
Java 属性名(大驼峰) | UserName |
$column.javaType |
Java 类型 | String / Long / Date |
$column.columnComment |
字段注释 | 用户账号 |
$column.isRequired |
是否必填 | true / false |
$column.isPk |
是否主键 | true / false |
$column.isInsert |
是否插入 | true / false |
$column.isEdit |
是否编辑 | true / false |
$column.isList |
是否列表字段 | true / false |
$column.isQuery |
是否查询字段 | true / false |
$column.queryType |
查询方式 | EQ / LIKE / BETWEEN |
$column.htmlType |
表单类型 | input / select / datetime |
$column.dictType |
字典类型 | sys_user_sex |
2.3 模板文件位置
ruoyi-generator 模块:
1 | ruoyi-generator/ |
三、三种生成模板类型
RuoYi 支持 3 种生成模板类型,适应不同的业务场景:
3.1 单表 CRUD(最常用)
适用场景
最常见的业务表,独立存在,无层级关系。
示例表:
1 | CREATE TABLE sys_user ( |
生成功能
- ✅ 列表查询 + 分页
- ✅ 新增
- ✅ 修改
- ✅ 删除(单个/批量)
- ✅ 导出 Excel
生成步骤
- 导入表:系统管理 → 代码生成 → 导入 → 选择
sys_user - 编辑配置:
- 基本信息:类名
SysUser,业务名user,功能名用户 - 字段信息:勾选”插入”、”编辑”、”列表”、”查询”
- 基本信息:类名
- 生成代码:点击”生成代码”,下载 ZIP
生成的 Controller 片段
1 |
|
3.2 树形表(Tree)
适用场景
部门、菜单、分类、区域 等树形层级结构。
核心字段
必须包含以下字段:
| 字段 | 说明 |
|---|---|
parent_id |
父节点 ID(0 表示根节点) |
ancestors |
祖级列表(如 0,100,101,用于快速查询子树) |
order_num |
排序字段 |
示例表:
1 | CREATE TABLE sys_dept ( |
生成功能
- ✅ 树形列表(递归构建)
- ✅ 新增子节点
- ✅ 修改/删除校验(不能删除有子节点的节点)
- ✅ 展开/折叠树节点
配置要点
编辑生成信息 → 生成信息 → 生成模板 → 选择”树表”:
- 树编码字段:
dept_id - 树父编码字段:
parent_id - 树名称字段:
dept_name
生成的 Service 片段
1 | /** |
3.3 主子表(一对多)
适用场景
订单-订单明细、合同-合同项、问卷-问题 等一对多关系。
表结构示例
主表(t_order):
1 | CREATE TABLE t_order ( |
子表(t_order_item):
1 | CREATE TABLE t_order_item ( |
生成功能
- ✅ 主表 CRUD
- ✅ 子表关联查询(
LEFT JOIN) - ✅ 新增时批量插入子表
- ✅ 修改时先删后插子表
- ✅ 删除时级联删除子表
配置要点
编辑主表生成信息 → 生成信息 → 生成模板 → 选择”主子表”:
- 关联子表的表名:
t_order_item - 子表关联的外键名:
order_id
生成的 Service 片段
1 | /** |
四、自定义模板开发
当默认生成的代码不满足需求时,可以自定义模板。
4.1 开发流程
3 个步骤:
- 复制原始模板:从
ruoyi-generator/resources/vm/java/controller.java.vm复制一份 - 修改模板内容:添加自定义方法、修改注解、调整包名
- 配置模板路径:在
VelocityInitializer中注册新模板
4.2 实战:添加批量导入方法
步骤 1:复制模板
1 | cd ruoyi-generator/src/main/resources/vm/java |
步骤 2:修改模板
在 controller-import.java.vm 中添加:
1 | /** |
步骤 3:配置模板路径
修改 GenTableServiceImpl.java,在 prepareContext() 方法中:
1 | VelocityContext context = new VelocityContext(); |
步骤 4:重新生成代码
重启 ruoyi-admin,重新导入表并生成代码,新的 Controller 会包含批量导入方法。
4.3 常见自定义场景
| 场景 | 修改模板 | 要点 |
|---|---|---|
| 添加统计接口 | controller.java.vm |
添加 @GetMapping("/stat") 方法 |
| 修改返回格式 | controller.java.vm |
将 AjaxResult 改为自定义 R<T> |
| 添加 DTO 转换 | serviceImpl.java.vm |
引入 MapStruct,添加转换逻辑 |
| 集成分布式 ID | domain.java.vm |
主键字段改为 @TableId(type = IdType.ASSIGN_ID) |
| 添加字段校验 | domain.java.vm |
添加 @NotNull、@Length、@Email 等注解 |
| 修改前端布局 | vue/index.vue.vm |
调整表格列宽、表单布局 |
4.4 模板调试技巧
问题:修改模板后生成的代码有语法错误?
调试方法:
- 查看 Velocity 日志:在
application.yml中开启日志:
1 | logging: |
- 单独测试模板:
1 |
|
- 检查变量是否存在:在模板中添加调试输出:
1 | ## 调试:输出所有变量 |
五、最佳实践
5.1 生成前的准备工作
规范表设计:
- 主键统一命名(如
表名_id) - 必须有
create_time、update_time、create_by、update_by - 字段注释完整(会生成到注解和前端表单)
- 主键统一命名(如
配置字典数据:
- 状态字段(如
status)关联字典类型sys_normal_disable - 性别字段关联
sys_user_sex - 前端会自动生成下拉框
- 状态字段(如
选择正确的查询方式:
- 精确查询:
EQ(等于) - 模糊查询:
LIKE(包含) - 范围查询:
BETWEEN(时间范围)
- 精确查询:
5.2 生成后的优化工作
生成的代码只是起点,需要手动优化:
- 添加业务校验:
1 |
|
- 优化 SQL 性能:
1 | <!-- 生成的 SQL 可能有冗余字段,按需精简 --> |
- 完善前端交互:
1 | <template> |
5.3 常见问题
(1)生成的菜单 SQL 如何使用?
问题:下载的 ZIP 中有 sql/menu.sql,如何导入?
答案:
- 打开
menu.sql,找到INSERT INTO sys_menu语句 - 修改
menu_id:避免与现有菜单冲突(查询SELECT MAX(menu_id) FROM sys_menu) - 在数据库中执行 SQL
- 刷新页面,左侧菜单自动出现
示例:
1 | -- 用户管理菜单 |
(2)生成的代码能直接运行吗?
答案:不能直接运行,需要手动集成。
步骤:
复制后端代码到对应模块:
Controller、Service、ServiceImpl→ruoyi-admin/src/main/java/com/ruoyi/web/controller/...Mapper.java→ruoyi-system/src/main/java/com/ruoyi/system/mapper/...Mapper.xml→ruoyi-system/src/main/resources/mapper/...Domain→ruoyi-system/src/main/java/com/ruoyi/system/domain/...
复制前端代码:
index.vue→ruoyi-ui/src/views/...api.js→ruoyi-ui/src/api/...
执行菜单 SQL:在数据库中插入菜单权限
重启后端,刷新前端页面
(3)如何生成多模块代码?
问题:项目分为 ruoyi-system、ruoyi-business、ruoyi-report 三个模块,如何指定生成到不同模块?
答案:修改生成配置中的 包路径。
编辑生成信息 → 生成信息 → 生成路径:
| 模块 | 包路径 |
|---|---|
ruoyi-system |
com.ruoyi.system |
ruoyi-business |
com.ruoyi.business |
ruoyi-report |
com.ruoyi.report |
生成后,代码会放在对应包下:
1 | com.ruoyi.business.controller.UserController |
结语
这篇文章深入剖析了 RuoYi 的代码生成器:
- 工作流程:配置生成信息 → 选择模板类型 → Velocity 渲染 → 生成前后端 7 个文件
- Velocity 语法:
$变量引用、#if 条件判断、#foreach 循环遍历、$table/$columns核心变量 - 三种模板类型:单表 CRUD(最常用)、树形表(parent_id + ancestors)、主子表(外键关联 + 级联操作)
- 自定义模板:复制 .vm 文件 → 添加业务逻辑 → 重新生成代码
- 最佳实践:规范表设计、配置字典、生成后优化(业务校验、SQL 性能、前端交互)
下一篇预告:我们将深入 RuoYi 的定时任务调度系统——Quartz 集成原理、Cron 表达式、任务执行日志、分布式任务调度改造。
思考与练习
- 尝试生成一个”商品管理”表(包含
product_name、price、stock字段),体验完整流程- 阅读
GenTableServiceImpl.java源码,理解代码生成的核心逻辑- 自定义一个模板,为所有 Controller 添加”导出 PDF”方法