代码生成器
概述
代码生成器可以快速生成标准化的 CRUD 代码,包括:
- 前端页面(列表、表单、详情)
- 后端接口(Controller、Service、Mapper)
- API 接口定义
- 数据库 SQL
使用场景
- 快速开发标准业务模块
- 保持代码风格统一
- 减少重复劳动
支持的后端
| 后端 | 模板引擎 | 状态 |
|---|---|---|
| Java · Spring Boot | Velocity | ✅ 支持 |
| Node · NestJS | Handlebars | ✅ 支持 |
| Go · Gin | Velty | ✅ 支持 |
| Python · Django | Jinja2 | ✅ 支持 |
| PHP · ThinkPHP | Blade | ✅ 支持 |
| C# · ASP.NET | T4 | ✅ 支持 |
使用步骤
1. 创建数据库表
sql
CREATE TABLE `sys_notice` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
`title` VARCHAR(100) NOT NULL COMMENT '标题',
`content` TEXT COMMENT '内容',
`type` TINYINT DEFAULT 1 COMMENT '类型(1 通知 2 公告)',
`status` TINYINT DEFAULT 1 COMMENT '状态(1 正常 0 关闭)',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='通知公告表';2. 配置生成参数
登录系统,进入「代码生成」菜单:
| 配置项 | 说明 |
|---|---|
| 表名 | 选择要生成的表 |
| 模块名 | 如 system |
| 业务名 | 如 notice |
| 功能名 | 如 通知公告 |
| 作者 | 生成代码的作者 |
| 上级菜单 | 生成的菜单挂载位置 |
3. 字段配置
| 字段 | 显示类型 | 查询方式 | 显示方式 |
|---|---|---|---|
| title | 输入框 | 模糊查询 | 列表显示 |
| content | 富文本 | - | 表单显示 |
| type | 字典选择 | 精确查询 | 列表显示 |
| status | 字典选择 | 精确查询 | 列表显示 |
| createTime | 日期范围 | 范围查询 | 列表显示 |
4. 生成代码
点击「生成代码」按钮,下载生成的压缩包。
5. 导入代码
解压后将代码复制到对应目录:
前端:
src/
├── api/system/notice.ts # API 接口
├── views/system/notice/
│ ├── index.vue # 列表页
│ └── components/
│ └── NoticeForm.vue # 表单组件后端:
src/main/java/
├── controller/system/NoticeController.java
├── service/system/NoticeService.java
├── mapper/system/NoticeMapper.java
└── entity/system/Notice.java生成的代码结构
前端页面
vue
<template>
<div class="app-container">
<!-- 搜索栏 -->
<el-form :model="queryParams" ref="queryFormRef" :inline="true">
<el-form-item label="标题" prop="title">
<el-input v-model="queryParams.title" placeholder="请输入标题" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 操作栏 -->
<el-row :gutter="10" class="mb-4">
<el-col :span="1.5">
<el-button type="primary" @click="handleAdd">新增</el-button>
</el-col>
</el-row>
<!-- 数据表格 -->
<el-table :data="dataList" v-loading="loading">
<el-table-column type="selection" width="55" />
<el-table-column label="标题" prop="title" />
<el-table-column label="类型" prop="type">
<template #default="{ row }">
<dict-tag type="notice_type" :value="row.type" />
</template>
</el-table-column>
<el-table-column label="操作" width="180">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
<el-button type="danger" link @click="handleDelete(row)">删除</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" />
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { listNotices, deleteNotice } from '@/api/system/notice'
const loading = ref(false)
const total = ref(0)
const dataList = ref([])
const queryParams = reactive({
pageNum: 1,
pageSize: 10,
title: ''
})
const getList = async () => {
loading.value = true
const { data } = await listNotices(queryParams)
dataList.value = data.list
total.value = data.total
loading.value = false
}
onMounted(() => {
getList()
})
</script>后端接口
java
@RestController
@RequestMapping("/api/v1/notices")
public class NoticeController {
@Autowired
private NoticeService noticeService;
@GetMapping
public Result<PageResult<Notice>> list(NoticeQuery query) {
PageResult<Notice> page = noticeService.list(query);
return Result.success(page);
}
@GetMapping("/{id}")
public Result<Notice> get(@PathVariable Long id) {
Notice notice = noticeService.getById(id);
return Result.success(notice);
}
@PostMapping
public Result<Void> add(@RequestBody @Valid NoticeForm form) {
noticeService.save(form);
return Result.success();
}
@PutMapping("/{id}")
public Result<Void> edit(@PathVariable Long id, @RequestBody @Valid NoticeForm form) {
noticeService.update(id, form);
return Result.success();
}
@DeleteMapping("/{ids}")
public Result<Void> delete(@PathVariable Long[] ids) {
noticeService.deleteByIds(ids);
return Result.success();
}
}自定义模板
如果默认模板不满足需求,可以自定义:
前端模板位置
youlai-boot/src/main/resources/templates/frontend/
├── api.ts.vm
├── index.vue.vm
└── form.vue.vm后端模板位置
youlai-boot/src/main/resources/templates/backend/
├── controller.java.vm
├── service.java.vm
├── serviceImpl.java.vm
├── mapper.java.vm
└── entity.java.vm模板变量
| 变量 | 说明 |
|---|---|
${tableName} | 表名 |
${className} | 类名 |
${moduleName} | 模块名 |
${businessName} | 业务名 |
${functionName} | 功能名 |
${author} | 作者 |
${datetime} | 生成时间 |
${columns} | 字段列表 |
示例模板
java
package ${packageName}.controller.${moduleName};
import ${packageName}.entity.${moduleName}.${className};
import ${packageName}.service.${moduleName}.${className}Service;
import org.springframework.web.bind.annotation.*;
/**
* ${functionName}Controller
*
* @author ${author}
* @date ${datetime}
*/
@RestController
@RequestMapping("/api/v1/${businessName}s")
public class ${className}Controller {
@Autowired
private ${className}Service ${businessName}Service;
@GetMapping
public Result list(${className}Query query) {
return Result.success(${businessName}Service.list(query));
}
}注意事项
- 生成后检查:生成代码后检查是否有语法错误
- 权限配置:需要手动配置菜单和按钮权限
- 字典配置:如果使用字典,需要先配置字典数据
- 表关联:不支持复杂的表关联,需要手动补充
- 命名规范:确保表名、字段名符合规范
最佳实践
- 先设计好数据库表结构
- 使用统一的命名规范
- 生成后先测试基本功能
- 根据业务需求调整代码
- 定制属于自己的模板
