第08章 - 代码生成器使用

第08章 - 代码生成器使用

8.1 代码生成器概述

8.1.1 功能介绍

RuoYi-Cloud提供了强大的代码生成器(ruoyi-gen模块),可以自动生成前后端代码,大大提高开发效率:

┌─────────────────────────────────────────────────────────────────────────────┐
│                          代码生成器功能                                      │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                         输入                                        │    │
│  │              数据库表 → 导入表结构 → 配置生成选项                     │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                │                                            │
│                                ▼                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                       代码生成引擎                                   │    │
│  │        Velocity模板引擎 + 表结构解析 + 字段映射                       │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                │                                            │
│                                ▼                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                         输出                                        │    │
│  ├───────────────┬───────────────┬───────────────┬───────────────────┤    │
│  │    Entity     │   Mapper      │   Service     │   Controller      │    │
│  │    实体类      │  XML/接口      │   服务层       │    控制层          │    │
│  ├───────────────┼───────────────┼───────────────┼───────────────────┤    │
│  │    Vue页面    │    API接口     │    SQL脚本    │    ......          │    │
│  └───────────────┴───────────────┴───────────────┴───────────────────┘    │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

8.1.2 支持的生成模式

模式 说明 适用场景
单表 单个数据库表生成CRUD 简单业务表
主子表 主表和子表生成关联CRUD 订单-订单明细
树表 树形结构表生成CRUD 部门、分类等

8.1.3 生成的文件清单

后端Java文件:

  • domain/实体类.java - 实体类
  • mapper/Mapper.java - MyBatis接口
  • mapper/xml/Mapper.xml - MyBatis映射文件
  • service/IService.java - 服务接口
  • service/impl/ServiceImpl.java - 服务实现
  • controller/Controller.java - 控制器

前端Vue文件:

  • views/模块/功能/index.vue - 列表页面
  • api/模块/功能.js - API接口

SQL文件:

  • sql/菜单.sql - 菜单SQL脚本

8.2 使用步骤

8.2.1 创建数据库表

首先创建需要生成代码的数据库表:

-- 创建测试表
CREATE TABLE `sys_test` (
    `test_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '测试ID',
    `test_name` varchar(50) NOT NULL COMMENT '测试名称',
    `test_code` varchar(50) DEFAULT NULL COMMENT '测试编码',
    `test_type` char(1) DEFAULT '0' COMMENT '测试类型(0类型1 1类型2)',
    `test_status` char(1) DEFAULT '0' COMMENT '状态(0正常 1停用)',
    `test_content` text COMMENT '测试内容',
    `test_date` datetime DEFAULT NULL COMMENT '测试日期',
    `create_by` varchar(64) DEFAULT '' COMMENT '创建者',
    `create_time` datetime DEFAULT NULL COMMENT '创建时间',
    `update_by` varchar(64) DEFAULT '' COMMENT '更新者',
    `update_time` datetime DEFAULT NULL COMMENT '更新时间',
    `remark` varchar(500) DEFAULT NULL COMMENT '备注',
    PRIMARY KEY (`test_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='测试表';

8.2.2 导入表结构

  1. 登录系统,进入【系统工具】-【代码生成】
  2. 点击【导入】按钮
  3. 选择需要生成代码的表
  4. 点击确认导入

8.2.3 配置生成选项

点击【编辑】按钮,配置生成选项:

基本信息:

  • 表名称:数据库表名
  • 表描述:功能描述
  • 实体类名称:Java实体类名
  • 作者:代码作者
  • 备注:其他备注

生成信息:

  • 生成模板:单表/树表/主子表
  • 生成包路径:com.ruoyi.xxx
  • 生成模块名:模块名称
  • 生成业务名:业务名称
  • 生成功能名:功能名称
  • 上级菜单:菜单归属
  • 生成代码方式:zip压缩包/自定义路径

字段信息:

  • 字段名称
  • 字段描述
  • 物理类型
  • Java类型
  • Java属性
  • 插入/编辑/列表/查询
  • 查询方式
  • 显示类型
  • 字典类型

8.2.4 预览和生成代码

  1. 点击【预览】按钮,查看将要生成的代码
  2. 确认无误后,点击【生成代码】
  3. 下载生成的压缩包或直接生成到指定路径

8.3 生成配置详解

8.3.1 基本配置

# gen配置
gen:
  # 作者
  author: ruoyi
  # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool
  packageName: com.ruoyi.system
  # 自动去除表前缀,默认是false
  autoRemovePre: false
  # 表前缀(生成类名不会包含表前缀,多个用逗号分隔)
  tablePrefix: sys_

8.3.2 字段类型映射

/**
 * 数据库类型到Java类型的映射
 */
public class GenConstants {
    /** 数据库字符串类型 */
    public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", 
        "varchar2", "tinytext", "text", "mediumtext", "longtext" };
    
    /** 数据库文本类型 */
    public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", 
        "mediumtext", "longtext" };
    
    /** 数据库时间类型 */
    public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };
    
    /** 数据库数字类型 */
    public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", 
        "int", "number", "integer", "bit", "bigint", "float", "double", "decimal" };
    
    /** 页面不需要编辑字段 */
    public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", 
        "del_flag" };
    
    /** 页面不需要显示的列表字段 */
    public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", 
        "del_flag", "update_by", "update_time" };
    
    /** 页面不需要查询字段 */
    public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", 
        "del_flag", "update_by", "update_time", "remark" };
}

8.3.3 HTML显示类型

类型 说明 组件
input 文本框 el-input
textarea 文本域 el-input type="textarea"
select 下拉框 el-select
radio 单选框 el-radio-group
checkbox 复选框 el-checkbox-group
datetime 日期控件 el-date-picker
imageUpload 图片上传 ImageUpload
fileUpload 文件上传 FileUpload
editor 富文本 Editor

8.3.4 查询方式

方式 说明 MyBatis条件
EQ 等于 =
NE 不等于 <>
GT 大于 >
GE 大于等于 >=
LT 小于 <
LE 小于等于 <=
LIKE 模糊查询 LIKE
BETWEEN 范围查询 BETWEEN

8.4 模板文件解析

8.4.1 模板文件位置

ruoyi-modules/ruoyi-gen/src/main/resources/vm/
├── java/
│   ├── controller.java.vm    # 控制器模板
│   ├── domain.java.vm        # 实体类模板
│   ├── mapper.java.vm        # Mapper接口模板
│   ├── service.java.vm       # Service接口模板
│   ├── serviceImpl.java.vm   # Service实现模板
│   └── sub-domain.java.vm    # 子表实体模板
├── xml/
│   └── mapper.xml.vm         # MyBatis XML模板
├── vue/
│   ├── index.vue.vm          # 列表页面模板
│   ├── index-tree.vue.vm     # 树表页面模板
│   └── api.js.vm             # API接口模板
└── sql/
    └── sql.vm                # 菜单SQL模板

8.4.2 实体类模板示例

package ${packageName}.domain;

#foreach ($import in $importList)
import ${import};
#end
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
#if($table.crud || $table.sub)
import com.ruoyi.common.core.web.domain.BaseEntity;
#elseif($table.tree)
import com.ruoyi.common.core.web.domain.TreeEntity;
#end

/**
 * ${functionName}对象 ${tableName}
 * 
 * @author ${author}
 * @date ${datetime}
 */
#if($table.crud || $table.sub)
public class ${ClassName} extends BaseEntity
#elseif($table.tree)
public class ${ClassName} extends TreeEntity
#end
{
    private static final long serialVersionUID = 1L;

#foreach ($column in $columns)
#if(!$table.isSuperColumn($column.javaField))
    /** $column.columnComment */
#if($column.list)
#set($parentheseIndex=$column.columnComment.indexOf("("))
#if($parentheseIndex != -1)
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
#else
#set($comment=$column.columnComment)
#end
#if($parentheseIndex != -1)
    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
#elseif($column.javaType == 'Date')
    @JsonFormat(pattern = "yyyy-MM-dd")
    @Excel(name = "${comment}", width = 30, dateFormat = "yyyy-MM-dd")
#else
    @Excel(name = "${comment}")
#end
#end
    private $column.javaType $column.javaField;

#end
#end
#if($table.sub)
    /** $table.subTable.functionName信息 */
    private List<${subClassName}> ${subclassName}List;

#end
#foreach ($column in $columns)
#if(!$table.isSuperColumn($column.javaField))
#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
#set($AttrName=$column.javaField)
#else
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#end
    public void set${AttrName}($column.javaType $column.javaField) 
    {
        this.$column.javaField = $column.javaField;
    }

    public $column.javaType get${AttrName}() 
    {
        return $column.javaField;
    }
#end
#end

#if($table.sub)
    public List<${subClassName}> get${subClassName}List()
    {
        return ${subclassName}List;
    }

    public void set${subClassName}List(List<${subClassName}> ${subclassName}List)
    {
        this.${subclassName}List = ${subclassName}List;
    }

#end
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
#foreach ($column in $columns)
#if($column.javaField.length() > 2 && $column.javaField.substring(1,2).matches("[A-Z]"))
#set($AttrName=$column.javaField)
#else
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#end
            .append("${column.javaField}", get${AttrName}())
#end
#if($table.sub)
            .append("${subclassName}List", get${subClassName}List())
#end
            .toString();
    }
}

8.4.3 控制器模板示例

package ${packageName}.controller;

import java.util.List;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import ${packageName}.domain.${ClassName};
import ${packageName}.service.I${ClassName}Service;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
#if($table.crud || $table.sub)
import com.ruoyi.common.core.web.page.TableDataInfo;
#elseif($table.tree)
#end

/**
 * ${functionName}Controller
 * 
 * @author ${author}
 * @date ${datetime}
 */
@RestController
@RequestMapping("/${businessName}")
public class ${ClassName}Controller extends BaseController
{
    @Autowired
    private I${ClassName}Service ${className}Service;

    /**
     * 查询${functionName}列表
     */
    @RequiresPermissions("${permissionPrefix}:list")
    @GetMapping("/list")
#if($table.crud || $table.sub)
    public TableDataInfo list(${ClassName} ${className})
    {
        startPage();
        List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
        return getDataTable(list);
    }
#elseif($table.tree)
    public AjaxResult list(${ClassName} ${className})
    {
        List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
        return success(list);
    }
#end

    /**
     * 导出${functionName}列表
     */
    @RequiresPermissions("${permissionPrefix}:export")
    @Log(title = "${functionName}", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ${ClassName} ${className})
    {
        List<${ClassName}> list = ${className}Service.select${ClassName}List(${className});
        ExcelUtil<${ClassName}> util = new ExcelUtil<${ClassName}>(${ClassName}.class);
        util.exportExcel(response, list, "${functionName}数据");
    }

    /**
     * 获取${functionName}详细信息
     */
    @RequiresPermissions("${permissionPrefix}:query")
    @GetMapping(value = "/{${pkColumn.javaField}}")
    public AjaxResult getInfo(@PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField})
    {
        return success(${className}Service.select${ClassName}By${pkColumn.capJavaField}(${pkColumn.javaField}));
    }

    /**
     * 新增${functionName}
     */
    @RequiresPermissions("${permissionPrefix}:add")
    @Log(title = "${functionName}", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ${ClassName} ${className})
    {
        return toAjax(${className}Service.insert${ClassName}(${className}));
    }

    /**
     * 修改${functionName}
     */
    @RequiresPermissions("${permissionPrefix}:edit")
    @Log(title = "${functionName}", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ${ClassName} ${className})
    {
        return toAjax(${className}Service.update${ClassName}(${className}));
    }

    /**
     * 删除${functionName}
     */
    @RequiresPermissions("${permissionPrefix}:remove")
    @Log(title = "${functionName}", businessType = BusinessType.DELETE)
	@DeleteMapping("/{${pkColumn.javaField}s}")
    public AjaxResult remove(@PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s)
    {
        return toAjax(${className}Service.delete${ClassName}By${pkColumn.capJavaField}s(${pkColumn.javaField}s));
    }
}

8.4.4 Vue页面模板示例

<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
#foreach($column in $columns)
#if($column.query)
#set($dictType=$column.dictType)
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#set($parentheseIndex=$column.columnComment.indexOf("("))
#if($parentheseIndex != -1)
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
#else
#set($comment=$column.columnComment)
#end
#if($column.htmlType == "input")
      <el-form-item label="${comment}" prop="${column.javaField}">
        <el-input
          v-model="queryParams.${column.javaField}"
          placeholder="请输入${comment}"
          clearable
          @keyup.enter="handleQuery"
        />
      </el-form-item>
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
      <el-form-item label="${comment}" prop="${column.javaField}">
        <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable>
          <el-option
            v-for="dict in ${dictType}"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType)
      <el-form-item label="${comment}" prop="${column.javaField}">
        <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable>
          <el-option label="请选择字典生成" value="" />
        </el-select>
      </el-form-item>
#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN")
      <el-form-item label="${comment}" prop="${column.javaField}">
        <el-date-picker clearable
          v-model="queryParams.${column.javaField}"
          type="date"
          value-format="YYYY-MM-DD"
          placeholder="请选择${comment}">
        </el-date-picker>
      </el-form-item>
#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
      <el-form-item label="${comment}" style="width: 308px">
        <el-date-picker
          v-model="daterange${AttrName}"
          value-format="YYYY-MM-DD"
          type="daterange"
          range-separator="-"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
        ></el-date-picker>
      </el-form-item>
#end
#end
#end
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="Plus"
          @click="handleAdd"
          v-hasPermi="['${moduleName}:${businessName}:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="Edit"
          :disabled="single"
          @click="handleUpdate"
          v-hasPermi="['${moduleName}:${businessName}:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="Delete"
          :disabled="multiple"
          @click="handleDelete"
          v-hasPermi="['${moduleName}:${businessName}:remove']"
        >删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="Download"
          @click="handleExport"
          v-hasPermi="['${moduleName}:${businessName}:export']"
        >导出</el-button>
      </el-col>
      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <!-- 表格数据 -->
    <el-table v-loading="loading" :data="${businessName}List" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
#foreach($column in $columns)
#set($javaField=$column.javaField)
#set($parentheseIndex=$column.columnComment.indexOf("("))
#if($parentheseIndex != -1)
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
#else
#set($comment=$column.columnComment)
#end
#if($column.pk)
      <el-table-column label="${comment}" align="center" prop="${javaField}" />
#elseif($column.list && $column.htmlType == "datetime")
      <el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
        <template #default="scope">
          <span>{% raw %}{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}{% endraw %}</span>
        </template>
      </el-table-column>
#elseif($column.list && $column.htmlType == "imageUpload")
      <el-table-column label="${comment}" align="center" prop="${javaField}" width="100">
        <template #default="scope">
          <image-preview :src="scope.row.${javaField}" :width="50" :height="50"/>
        </template>
      </el-table-column>
#elseif($column.list && "" != $column.dictType)
      <el-table-column label="${comment}" align="center" prop="${javaField}">
        <template #default="scope">
#if($column.htmlType == "checkbox")
          <dict-tag :options="${column.dictType}" :value="scope.row.${javaField} ? scope.row.${javaField}.split(',') : []"/>
#else
          <dict-tag :options="${column.dictType}" :value="scope.row.${javaField}"/>
#end
        </template>
      </el-table-column>
#elseif($column.list && "" != $javaField)
      <el-table-column label="${comment}" align="center" prop="${javaField}" />
#end
#end
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template #default="scope">
          <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${moduleName}:${businessName}:edit']">修改</el-button>
          <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${moduleName}:${businessName}:remove']">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    
    <pagination
      v-show="total>0"
      :total="total"
      v-model:page="queryParams.pageNum"
      v-model:limit="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 添加或修改${functionName}对话框 -->
    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
      <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
        <!-- 表单字段 -->
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="${BusinessName}">
// 脚本内容...
</script>

8.5 主子表生成

8.5.1 主子表结构

-- 主表:订单表
CREATE TABLE `biz_order` (
    `order_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '订单ID',
    `order_no` varchar(50) NOT NULL COMMENT '订单号',
    `customer_name` varchar(100) DEFAULT NULL COMMENT '客户名称',
    `order_amount` decimal(10,2) DEFAULT NULL COMMENT '订单金额',
    `order_status` char(1) DEFAULT '0' COMMENT '订单状态',
    `order_time` datetime DEFAULT NULL COMMENT '下单时间',
    `create_by` varchar(64) DEFAULT '' COMMENT '创建者',
    `create_time` datetime DEFAULT NULL COMMENT '创建时间',
    `update_by` varchar(64) DEFAULT '' COMMENT '更新者',
    `update_time` datetime DEFAULT NULL COMMENT '更新时间',
    `remark` varchar(500) DEFAULT NULL COMMENT '备注',
    PRIMARY KEY (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='订单表';

-- 子表:订单明细表
CREATE TABLE `biz_order_item` (
    `item_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '明细ID',
    `order_id` bigint(20) NOT NULL COMMENT '订单ID',
    `product_name` varchar(100) DEFAULT NULL COMMENT '商品名称',
    `product_price` decimal(10,2) DEFAULT NULL COMMENT '商品单价',
    `quantity` int(11) DEFAULT NULL COMMENT '数量',
    `amount` decimal(10,2) DEFAULT NULL COMMENT '金额',
    PRIMARY KEY (`item_id`),
    KEY `idx_order_id` (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='订单明细表';

8.5.2 主子表配置

  1. 先导入主表和子表
  2. 编辑主表,选择"主子表"模板
  3. 配置关联子表和关联外键字段
  4. 生成代码

8.5.3 生成代码说明

主子表生成后,会包含子表数据的增删改查功能,实现主从联动。

8.6 树表生成

8.6.1 树表结构

-- 树形分类表
CREATE TABLE `biz_category` (
    `category_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分类ID',
    `parent_id` bigint(20) DEFAULT 0 COMMENT '父分类ID',
    `ancestors` varchar(500) DEFAULT '' COMMENT '祖级列表',
    `category_name` varchar(50) NOT NULL COMMENT '分类名称',
    `order_num` int(4) DEFAULT 0 COMMENT '显示顺序',
    `status` char(1) DEFAULT '0' COMMENT '状态(0正常 1停用)',
    `create_by` varchar(64) DEFAULT '' COMMENT '创建者',
    `create_time` datetime DEFAULT NULL COMMENT '创建时间',
    `update_by` varchar(64) DEFAULT '' COMMENT '更新者',
    `update_time` datetime DEFAULT NULL COMMENT '更新时间',
    PRIMARY KEY (`category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='分类表';

8.6.2 树表必要字段

字段 说明
id 主键
parent_id 父级ID
ancestors 祖级列表(可选,用于快速查询)
order_num 排序字段(可选)

8.6.3 树表配置

  1. 导入树形结构表
  2. 编辑表,选择"树表"模板
  3. 配置树编码(主键)、树父编码(父级ID)、树名称字段
  4. 生成代码

8.7 代码使用

8.7.1 后端代码部署

  1. 将生成的Java代码复制到对应模块
  2. 复制Mapper XML文件到resources/mapper目录
  3. 确保包路径正确

8.7.2 前端代码部署

  1. 将Vue文件复制到views目录
  2. 将API文件复制到api目录
  3. 执行菜单SQL脚本

8.7.3 菜单配置

-- 菜单SQL示例
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
VALUES('测试管理', '1', '1', 'test', 'system/test/index', 1, 0, 'C', '0', '0', 'system:test:list', '#', 'admin', sysdate(), '', null, '测试管理菜单');

-- 按钮权限
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
VALUES('测试查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', 'system:test:query', '#', 'admin', sysdate(), '', null, '');

INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
VALUES('测试新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', 'system:test:add', '#', 'admin', sysdate(), '', null, '');

INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
VALUES('测试修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', 'system:test:edit', '#', 'admin', sysdate(), '', null, '');

INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
VALUES('测试删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', 'system:test:remove', '#', 'admin', sysdate(), '', null, '');

INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
VALUES('测试导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', 'system:test:export', '#', 'admin', sysdate(), '', null, '');

8.8 小结

本章详细介绍了RuoYi-Cloud代码生成器的使用方法,包括:

  1. 生成器功能:支持单表、主子表、树表三种模式
  2. 使用步骤:创建表、导入、配置、生成
  3. 配置详解:字段类型映射、显示类型、查询方式
  4. 模板解析:Velocity模板文件结构
  5. 代码部署:后端、前端代码的使用方法

代码生成器可以大大提高开发效率,是RuoYi-Cloud的核心工具之一。


上一章:系统管理模块 | 返回目录 | 下一章:定时任务模块

posted @ 2026-01-08 14:05  我才是银古  阅读(14)  评论(0)    收藏  举报