RuoYi-Vue代码生成:自定义模板开发
还在为重复的CRUD代码编写而烦恼?RuoYi-Vue的代码生成器提供了强大的自定义模板功能,让你能够根据项目需求定制化生成代码。本文将深入解析RuoYi-Vue的模板机制,手把手教你如何开发自定义模板。
模板引擎核心机制
RuoYi-Vue使用Apache Velocity作为模板引擎,通过预定义的变量和逻辑控制代码生成过程。
模板目录结构
ruoyi-generator/src/main/resources/vm/
├── java/ # Java后端模板
│ ├── domain.java.vm
│ ├── mapper.java.vm
│ ├── service.java.vm
│ ├── serviceImpl.java.vm
│ ├── controller.java.vm
│ └── sub-domain.java.vm
├── xml/ # MyBatis映射文件模板
│ └── mapper.xml.vm
├── sql/ # SQL菜单模板
│ └── sql.vm
├── js/ # JavaScript API模板
│ └── api.js.vm
└── vue/ # Vue前端模板
├── index.vue.vm
├── index-tree.vue.vm
└── v3/ # Vue3版本模板
模板变量详解
核心上下文变量
| 变量名 | 类型 | 描述 | 示例 |
|---|---|---|---|
tableName | String | 数据库表名 | sys_user |
ClassName | String | Java类名(首字母大写) | SysUser |
className | String | Java类名(首字母小写) | sysUser |
BusinessName | String | 业务名称(首字母大写) | User |
businessName | String | 业务名称(首字母小写) | user |
moduleName | String | 模块名称 | system |
packageName | String | 包名 | com.ruoyi.system |
functionName | String | 功能名称 | 用户管理 |
author | String | 作者 | ruoyi |
datetime | String | 当前时间 | 2025-01-01 |
columns | List | 列信息列表 | - |
pkColumn | Object | 主键列信息 | - |
列对象属性
public class GenTableColumn {
private String columnName; // 列名
private String columnComment; // 列注释
private String javaType; // Java类型
private String javaField; // Java字段名
private String htmlType; // HTML控件类型
private String dictType; // 字典类型
private boolean isInsert; // 是否插入字段
private boolean isEdit; // 是否编辑字段
private boolean isList; // 是否列表字段
private boolean isQuery; // 是否查询字段
private String queryType; // 查询方式
}
Velocity模板语法实战
条件判断
#if($column.htmlType == "select")
<!-- 下拉选择框 -->
#elseif($column.htmlType == "radio")
<!-- 单选框 -->
#else
<!-- 默认输入框 -->
#end
循环遍历
#foreach($column in $columns)
#if($column.query)
<!-- 生成查询条件 -->
#end
#end
方法调用
$column.javaField.substring(0,1).toUpperCase()${column.javaField.substring(1)}
自定义模板开发指南
1. 创建新模板文件
在vm目录下创建新的模板文件,例如自定义的Service模板:
## custom-service.java.vm
package ${packageName}.service;
import ${packageName}.domain.${ClassName};
import java.util.List;
/**
* ${functionName}服务层
*
* @author ${author}
* @date ${datetime}
*/
public interface Custom${ClassName}Service
{
/**
* 查询${functionName}
*
* @param ${pkColumn.javaField} ${functionName}ID
* @return ${functionName}
*/
${ClassName} selectCustom${ClassName}By${pkColumn.javaField.substring(0,1).toUpperCase()}${pkColumn.javaField.substring(1)}(${pkColumn.javaType} ${pkColumn.javaField});
/**
* 查询${functionName}列表
*
* @param ${className} ${functionName}
* @return ${functionName}集合
*/
List<${ClassName}> selectCustom${ClassName}List(${ClassName} ${className});
/**
* 新增${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
int insertCustom${ClassName}(${ClassName} ${className});
/**
* 修改${functionName}
*
* @param ${className} ${functionName}
* @return 结果
*/
int updateCustom${ClassName}(${ClassName} ${className});
/**
* 批量删除${functionName}
*
* @param ${pkColumn.javaField}s 需要删除的${functionName}ID
* @return 结果
*/
int deleteCustom${ClassName}By${pkColumn.javaField.substring(0,1).toUpperCase()}${pkColumn.javaField.substring(1)}s(${pkColumn.javaType}[] ${pkColumn.javaField}s);
}
2. 修改模板配置
在VelocityUtils.java中添加新的模板路径:
public static List<String> getTemplateList(String tplCategory, String tplWebType)
{
List<String> templates = new ArrayList<String>();
// 原有模板...
templates.add("vm/java/custom-service.java.vm"); // 新增自定义模板
return templates;
}
3. 配置文件名生成规则
在getFileName方法中添加文件名生成逻辑:
else if (template.contains("custom-service.java.vm"))
{
fileName = StringUtils.format("{}/service/Custom{}Service.java", javaPath, className);
}
高级模板技巧
自定义业务逻辑
## 自定义业务逻辑处理
#set($customBusiness = "")
#foreach($column in $columns)
#if($column.javaField == "status")
#set($customBusiness = $customBusiness + "
/**
* 根据状态查询${functionName}
*/
List<${ClassName}> selectByStatus(String status);")
#end
#end
$customBusiness
模板继承与组合
## base-template.vm - 基础模板
#macro(commonImports)
import java.util.List;
import java.util.Date;
#end
#macro(commonMethods $entity)
/**
* 查询所有${entity}
*/
List<${entity}> selectAll();
/**
* 统计数量
*/
int count();
#end
## 具体业务模板
#parse("base-template.vm")
public interface ${ClassName}Service {
#commonImports
#commonMethods(${ClassName})
// 业务特定方法
}
实战案例:生成GraphQL接口
GraphQL Schema模板
## graphql/schema.graphql.vm
type ${ClassName} {
#foreach($column in $columns)
${column.javaField}: ${getGraphQLType($column.javaType)}
#end
}
type Query {
#foreach($column in $columns)
#if($column.isQuery)
${businessName}By${column.javaField.substring(0,1).toUpperCase()}${column.javaField.substring(1)}(${column.javaField}: ${getGraphQLType($column.javaType)}): ${ClassName}
#end
#end
all${BusinessName}: [${ClassName}]
}
type Mutation {
create${BusinessName}(input: ${ClassName}Input): ${ClassName}
update${BusinessName}(id: ID!, input: ${ClassName}Input): ${ClassName}
delete${BusinessName}(id: ID!): Boolean
}
input ${ClassName}Input {
#foreach($column in $columns)
#if(!$column.isPk)
${column.javaField}: ${getGraphQLType($column.javaType)}
#end
#end
}
类型映射工具方法
#macro(getGraphQLType $javaType)
#if($javaType == "String")"String"#
#elseif($javaType == "Integer")"Int"#
#elseif($javaType == "Long")"Long"#
#elseif($javaType == "Date")"String"#
#elseif($javaType == "BigDecimal")"Float"#
#else"String"#end
#end
模板调试与测试
调试技巧
- 输出变量值:
## 调试输出
<!-- $column.javaField = $column.javaField -->
<!-- $column.htmlType = $column.htmlType -->
- 条件调试:
#if($debug)
<!-- 调试信息:columnCount = $columns.size() -->
#end
单元测试模板
创建测试数据验证模板输出:
@Test
public void testCustomTemplate() {
GenTable genTable = createTestGenTable();
VelocityContext context = VelocityUtils.prepareContext(genTable);
String result = VelocityUtils.mergeTemplate("vm/java/custom-service.java.vm", context);
assertThat(result).contains("CustomUserService");
assertThat(result).contains("selectCustomUserById");
}
最佳实践与注意事项
模板设计原则
- 单一职责:每个模板只负责生成一种类型的文件
- 可配置性:通过变量控制生成逻辑,避免硬编码
- 可维护性:保持模板简洁,复杂的逻辑移到工具类中
- 兼容性:确保新模板与现有系统兼容
常见问题解决
性能优化建议
- 减少嵌套循环:避免在模板中使用多层嵌套循环
- 预计算复杂逻辑:在Java代码中预先计算好复杂数据
- 使用宏定义:将重复代码提取为宏
- 缓存模板:对不经常变化的模板进行缓存
总结
通过掌握RuoYi-Vue的模板开发技术,你可以:
- ✅ 根据业务需求定制化生成代码
- ✅ 统一项目代码风格和规范
- ✅ 大幅提升开发效率和代码质量
- ✅ 适应各种技术栈和架构要求
模板开发是RuoYi-Vue代码生成器的核心能力,熟练掌握后能够为项目带来巨大的开发效率提升。建议从简单的模板修改开始,逐步深入到复杂的自定义模板开发。
下一步学习建议:
- 深入研究Velocity模板引擎语法
- 学习更多模板设计模式
- 实践企业级模板开发案例
- 参与RuoYi-Vue社区贡献模板
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



