create-base-teek-theme
Version:
``` npm create base-teek-theme@latest my-first-blog ```
592 lines (456 loc) • 17.5 kB
Markdown
---
date: 2025-04-15 09:28:08
title: 代码生成器
permalink: /pages/ddce09
top: 4
tags:
- Spring Boot
author:
name: 华总
link: https://xiaoying.org.cn
categories:
- 后端
- 功能扩展
---
# Spring Boot 代码生成器
基于Spring Boot + Velocity的代码生成器,用于快速生成项目代码,提高开发效率。
## 简介
这是一个基于Spring Boot 的代码生成器,支持通过数据库表结构自动生成Controller、Service、Mapper、Entity等相关代码,大幅提高开发效率。
## 特性
- 使用Velocity模板引擎生成代码
- 支持自定义模板
- 支持多种代码生成模式
- 支持字段级别的配置(表单显示、列表显示、查询条件等)
- 支持代码预览和下载
## 快速开始
### 1. 基本配置
#### 1.1 引入依赖
::: tip
依赖可能非最新版本,请前往maven获取最新版本
[Spring Boot 2](https://central.sonatype.com/artifact/io.github.liyao52033/spring-boot-starter-codegen)地址
[Spring Boot 3](https://central.sonatype.com/artifact/io.github.liyao52033/liyao-spring-boot3-starter-codegen)地址
:::
在您的Spring Boot项目的`pom.xml`中添加以下依赖
Spring Boot 2(java8)
```xml
<dependency>
<groupId>io.github.liyao52033</groupId>
<artifactId>spring-boot-starter-codegen</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>io.github.liyao52033</groupId>
<artifactId>ErrorCode-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
```
Spring Boot 3(java17)
```xml
<dependency>
<groupId>io.github.liyao52033</groupId>
<artifactId>liyao-spring-boot3-starter-codegen</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>io.github.liyao52033</groupId>
<artifactId>liyao-spring-boot3-starter-ErrorCode</artifactId>
<version>1.2.0</version>
</dependency>
```
#### 1.2 配置mysql与mybatis-plus
```yml
// 引入相关依赖并配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo
username: mysql账号
password: mysql密码
// 依赖中用到了mybatis-plus,直接配置即可
mybatis-plus:
configuration:
map-underscore-to-camel-case: false
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath*:mapper/*.xml
global-config:
db-config:
logic-delete-field: isDelete # 全局逻辑删除的实体字段名
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
```
#### 1.3 新建数据库表
```sql
-- ----------------------------
-- Table structure for gen_config
-- ----------------------------
DROP TABLE IF EXISTS `gen_config`;
CREATE TABLE `gen_config` (
`id` bigint NOT NULL,
`tableName` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '表名',
`moduleName` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模块名',
`packageName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '包名',
`businessName` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '业务名',
`entityName` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '实体类名',
`author` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '作者',
`parentMenuId` bigint NULL DEFAULT NULL COMMENT '父目录id',
`createTime` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
`updateTime` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`isDelete` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_tablename`(`tableName` ASC) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代码生成基础配置表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for gen_field_config
-- ----------------------------
DROP TABLE IF EXISTS `gen_field_config`;
CREATE TABLE `gen_field_config` (
`id` bigint NOT NULL,
`configId` bigint NOT NULL COMMENT '关联的配置ID',
`columnName` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`columnType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`columnLength` int NULL DEFAULT NULL,
`fieldName` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '字段名称',
`fieldType` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '字段类型',
`fieldSort` int NULL DEFAULT NULL COMMENT '字段排序',
`fieldComment` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '字段描述',
`maxLength` int NULL DEFAULT NULL,
`isRequired` tinyint(1) NULL DEFAULT NULL COMMENT '是否必填',
`isShowInList` tinyint(1) NULL DEFAULT 0 COMMENT '是否在列表显示',
`isShowInForm` tinyint(1) NULL DEFAULT 0 COMMENT '是否在表单显示',
`isShowInQuery` tinyint(1) NULL DEFAULT 0 COMMENT '是否在查询条件显示',
`queryType` tinyint NULL DEFAULT NULL COMMENT '查询方式',
`formType` tinyint NULL DEFAULT NULL COMMENT '表单类型',
`dictType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '字典类型',
`createTime` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
`updateTime` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`isDelete` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除',
PRIMARY KEY (`id`) USING BTREE,
INDEX `config_id`(`configId` ASC) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代码生成字段配置表' ROW_FORMAT = Dynamic;
```
### 2. 配置代码生成器
在您的`codegen.yml`或文件中添加以下配置:
```yaml
liyao:
codegen:
# 生成模式可选 tree(完整项目结构), simple(按照输入目录的文件结构输出)
mode: simple
# 模板文件路径
template-dir: templates/velocity
# 生成代码到本地的路径
output-dir: templates/generator
# 下载代码文件名称
downloadFileName: youlai-admin-code.zip
# 后端项目名称
backendAppName: java
# 前端项目名称
frontendAppName: vue
# 排除数据表,下面两个必须排除,如果还有其他的不需要生成也可以添加
excludeTables:
- gen_config
- gen_field_config
#默认配置
default-config:
#包名
package-name: com.youlai
# 模块名
module-name: system
# 作者
author: liyao
## 模板配置
templateConfigs:
# ${subpackageName}变量(子包)对应的文件名称,前端vue模板固定为 VIEW,vue生成的文件名为 index.vue,多个vue放不同的文件夹
VIEW:
templatePath: index.vue.vm
subpackageName: views
extension: .vue
# 前端接口
API:
templatePath: api.ts.vm
subpackageName: api
extension: .ts
# 子包文件名称,例如下面为 Controller,实体类 User, extension为空默认为 .java, 生成的文件名为 UserController.java
Controller:
# 模板文件存放路径
templatePath: controller.java.vm
# 子包名,例如上面生成的UserController.java就放在 controller包下
subpackageName: controller
Service:
templatePath: service.java.vm
subpackageName: service
ServiceImpl:
templatePath: serviceImpl.java.vm
subpackageName: service.impl
Mapper:
templatePath: mapper.java.vm
subpackageName: mapper
MapperXml:
templatePath: mapper.xml.vm
subpackageName: mapper
extension: .xml
Converter:
templatePath: converter.java.vm
subpackageName: converter
QueryRequest:
templatePath: model/QueryRequest.java.vm
subpackageName: model.form
Form:
templatePath: model/form.java.vm
subpackageName: model.form
AddRequest:
templatePath: model/AddRequest.java.vm
subpackageName: model.form
UpdateRequest:
templatePath: model/UpdateRequest.java.vm
subpackageName: model.form
EditRequest:
templatePath: model/EditRequest.java.vm
subpackageName: model.form
VO:
templatePath: model/VO.java.vm
subpackageName: model.vo
Entity:
templatePath: model/entity.java.vm
subpackageName: model.entity
```
在`application.yml`引入
```yml
spring:
config:
import: classpath:codegen.yml
```
### 3. 使用代码生成器
代码生成器会自动注册到您的Spring Boot应用中,您可以通过以下方式使用:
#### 3.1 注入代码生成服务
```java
@Resource
private CodegenService codegenService;
@Resource
private GenConfigService genConfigService;
@Resource
private CodegenProperties codegenProperties;
```
#### 3.2 获取数据库表列表
可通过以下接口获取所有数据库列表
```java
@Operation(summary = "获取数据表分页列表")
@GetMapping("/table/page")
public PageResultUtils<TablePageVO> getTablePage(TablePageQuery queryParams) {
Page<TablePageVO> result = codegenService.getTablePage(queryParams);
return PageResultUtils.success(result);
}
```
#### 3.3 获取代码生成配置
获取指定表的配置
```java
@Operation(summary = "获取代码生成配置")
@GetMapping("/{tableName}/config")
public BaseResponse<GenConfigForm> getGenConfigFormData(
@Parameter(description = "表名") @PathVariable String tableName)
{
GenConfigForm formData = genConfigService.getGenConfigFormData(tableName);
return ResultUtils.success(formData);
}
```
#### 3.4 修改代码生成配置
```java
@Operation(summary = "修改代码生成配置")
@PostMapping("/{tableName}/config")
public BaseResponse<Boolean> saveGenConfig(@PathVariable String tableName, @RequestBody GenConfigForm formData) {
formData.setTableName(tableName);
return genConfigService.saveGenConfig(formData);
}
```
示例配置如下
```java
{
"id": 311,
"tableName": "user", //表名
"businessName": "用户信息", //表备注
"moduleName": "springbootInit", //包名
"packageName": "com.starter", // 模块名
"entityName": "User", //表实体类名
"author": "liyao", //作者
"fieldConfigs": [ //表字段配置
{
"id": 3864,
"columnName": "id", //列名
"columnType": "bigint", //列类型
"fieldName": "id", // 字段名
"fieldSort": 1, //字段排序
"fieldType": "Long", // 字段类型
"fieldComment": "id", // 字段说明
"isShowInList": 0, // 是否显示在显示列表中
"isShowInForm": 0, //是否用于表单中(用于增删改查)
"isShowInQuery": 0, //字段是否用于查询
"isRequired": 0 // 是否必须
"maxLength": 64, //字段最大长度
"formType": 1, // 表单类型,见下方字段配置
"queryType": 2 //查询类型, 见下方字段配置
}
}
```
#### 3.5 删除代码生成配置
```java
@Operation(summary = "删除代码生成配置")
@DeleteMapping("/{tableName}/config")
public BaseResponse<Boolean> deleteGenConfig(
@Parameter(description = "表名") @PathVariable String tableName)
{
return genConfigService.deleteGenConfig(tableName);
}
```
#### 3.6预览生成的代码
```java
@Operation(summary = "获取预览生成代码")
@GetMapping("/{tableName}/preview")
public BaseResponse<List<CodegenPreviewVO>> getTablePreviewData(@PathVariable String tableName) {
List<CodegenPreviewVO> list = codegenService.getCodegenPreviewData(tableName);
return ResultUtils.success(list);
}
```
#### 3.7 生成代码到本地项目
生成到yml配置的outputDir指定的路径
```java
@Operation(summary = "生成代码到本地")
@GetMapping("/{tableName}/gen")
public BaseResponse<List<String>> generateCode(@PathVariable String tableName) {
List<String> generatedFile = codegenService.generateFile(tableName);
return ResultUtils.success(generatedFile);
}
```
#### 3.8 下载生成的代码压缩包
```java
@Operation(summary = "下载代码")
@GetMapping("/{tableName}/download")
public void downloadZip(HttpServletResponse response, @PathVariable String tableName) throws UnsupportedEncodingException {
String[] tableNames = tableName.split(",");
byte[] data = codegenService.downloadCode(tableNames);
response.reset();
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(codegenProperties.getDownloadFileName(), "UTF-8"));
response.setContentType("application/octet-stream; charset=UTF-8");
try (ServletOutputStream outputStream = response.getOutputStream()) {
outputStream.write(data);
outputStream.flush();
} catch (IOException e) {
log.error("Error while writing the zip file to response", e);
throw new RuntimeException("Failed to write the zip file to response", e);
}
}
```
## 代码生成模式
代码生成器支持两种模式:
### 1. 简单模式 (simple)
简单模式下,代码生成器会根据模板目录中的所有`.vm`文件生成代码,根据给定模板的文件结构生成同样的目录,适合简单的代码生成需求
### 2. 树形结构模式 (tree)
树形结构模式下,代码生成器会根据配置的模板配置生成代码,支持更复杂的代码生成需求,可以精确控制每个模板的生成路径和文件名,会生成完整的springBoot项目结构
## 自定义模板
您可以通过以下步骤自定义代码生成模板,`src/main/resources/`作为模板根目录
1. 在您的项目中创建模板目录,例如`templates/codegen`
2. 在该目录下创建Velocity模板文件,例如`controller.java.vm`、`service.java.vm`等
3. 在配置中指定模板目录:`liyao.codegen.template-dir=/templates/codegen`
模板文件中可以使用以下变量:
- `${packageName}`: 包名
- `${moduleName}`: 模块名
- `${subpackageName}`: 子包名(tree模式专属)
- `${entityName}`: 实体类名
- `${tableName}`: 表名
- `${businessName}`: 表备注
- `${author}`: 作者
- `${fieldConfigs}`: 字段配置列表
## 字段配置
代码生成器支持对每个字段进行详细配置:
- **字段名称**: 数据库字段名
- **字段类型**: Java类型,如String、Integer等
- **字段注释**: 字段说明
- **是否必填**: 是否为必填字段
- **是否在列表显示**: 是否在列表页面显示
- **是否在表单显示**: 是否在表单页面显示
- **是否为查询条件**: 是否作为查询条件
- **查询方式**: 等于、模糊查询、大于、小于等
```java
// queryType可选值
/** 等于 */
EQ(1, "="),
/** 模糊匹配 */
LIKE(2, "LIKE '%s%'"),
/** 包含 */
IN(3, "IN"),
/** 范围 */
BETWEEN(4, "BETWEEN"),
/** 大于 */
GT(5, ">"),
/** 大于等于 */
GE(6, ">="),
/** 小于 */
LT(7, "<"),
/** 小于等于 */
LE(8, "<="),
/** 不等于 */
NE(9, "!="),
/** 左模糊匹配 */
LIKE_LEFT(10, "LIKE '%s'"),
/** 右模糊匹配 */
LIKE_RIGHT(11, "LIKE 's%'");
```
- **表单类型**: 输入框、下拉框、日期选择器等
```java
// formType
/**
* 输入框
*/
INPUT(1, "输入框"),
/**
* 下拉框
*/
SELECT(2, "下拉框"),
/**
* 单选框
*/
RADIO(3, "单选框"),
/**
* 复选框
*/
CHECK_BOX(4, "复选框"),
/**
* 数字输入框
*/
INPUT_NUMBER(5, "数字输入框"),
/**
* 开关
*/
SWITCH(6, "开关"),
/**
* 文本域
*/
TEXT_AREA(7, "文本域"),
/**
* 日期时间框
*/
DATE(8, "日期框"),
/**
* 日期框
*/
DATE_TIME(9, "日期时间框"),
/**
* 隐藏域
*/
HIDDEN(10, "隐藏域");
```
## 高级配置
### 排除特定表
您可以通过配置`liyao.codegen.exclude-tables`排除不需要生成代码的表:
```yaml
liyao:
codegen:
exclude-tables:
- sys_user
- sys_role
```
### 自定义输出目录
您可以通过配置`liyao.codegen.output-dir`自定义代码输出目录:
```yaml
liyao:
codegen:
output-dir: generated-code
```