---
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
```