RuoYi-Vue代码生成:自定义模板开发

RuoYi-Vue代码生成:自定义模板开发

【免费下载链接】RuoYi-Vue 🎉 基于SpringBoot,Spring Security,JWT,Vue & Element 的前后端分离权限管理系统,同时提供了 Vue3 的版本 【免费下载链接】RuoYi-Vue 项目地址: https://gitcode.com/yangzongzhuan/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版本模板

模板变量详解

核心上下文变量

变量名类型描述示例
tableNameString数据库表名sys_user
ClassNameStringJava类名(首字母大写)SysUser
classNameStringJava类名(首字母小写)sysUser
BusinessNameString业务名称(首字母大写)User
businessNameString业务名称(首字母小写)user
moduleNameString模块名称system
packageNameString包名com.ruoyi.system
functionNameString功能名称用户管理
authorString作者ruoyi
datetimeString当前时间2025-01-01
columnsList列信息列表-
pkColumnObject主键列信息-

列对象属性

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

模板调试与测试

调试技巧

  1. 输出变量值
## 调试输出
<!-- $column.javaField = $column.javaField -->
<!-- $column.htmlType = $column.htmlType -->
  1. 条件调试
#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");
}

最佳实践与注意事项

模板设计原则

  1. 单一职责:每个模板只负责生成一种类型的文件
  2. 可配置性:通过变量控制生成逻辑,避免硬编码
  3. 可维护性:保持模板简洁,复杂的逻辑移到工具类中
  4. 兼容性:确保新模板与现有系统兼容

常见问题解决

mermaid

性能优化建议

  1. 减少嵌套循环:避免在模板中使用多层嵌套循环
  2. 预计算复杂逻辑:在Java代码中预先计算好复杂数据
  3. 使用宏定义:将重复代码提取为宏
  4. 缓存模板:对不经常变化的模板进行缓存

总结

通过掌握RuoYi-Vue的模板开发技术,你可以:

  • ✅ 根据业务需求定制化生成代码
  • ✅ 统一项目代码风格和规范
  • ✅ 大幅提升开发效率和代码质量
  • ✅ 适应各种技术栈和架构要求

模板开发是RuoYi-Vue代码生成器的核心能力,熟练掌握后能够为项目带来巨大的开发效率提升。建议从简单的模板修改开始,逐步深入到复杂的自定义模板开发。

下一步学习建议

  • 深入研究Velocity模板引擎语法
  • 学习更多模板设计模式
  • 实践企业级模板开发案例
  • 参与RuoYi-Vue社区贡献模板

【免费下载链接】RuoYi-Vue 🎉 基于SpringBoot,Spring Security,JWT,Vue & Element 的前后端分离权限管理系统,同时提供了 Vue3 的版本 【免费下载链接】RuoYi-Vue 项目地址: https://gitcode.com/yangzongzhuan/RuoYi-Vue

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值