Spring Boot 代码生成器

基于Spring Boot + Velocity的代码生成器,用于快速生成项目代码,提高开发效率。

简介

这是一个基于Spring Boot 的代码生成器,支持通过数据库表结构自动生成Controller、Service、Mapper、Entity等相关代码,大幅提高开发效率。

特性

  • 使用Velocity模板引擎生成代码
  • 支持自定义模板
  • 支持多种代码生成模式
  • 支持字段级别的配置(表单显示、列表显示、查询条件等)
  • 支持代码预览和下载

快速开始

_1. 基本配置

_1.1 引入依赖

在您的Spring Boot项目的pom.xml中添加以下依赖

Spring Boot 2(java8)

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

      <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

      // 引入相关依赖并配置
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 新建数据库表

      -- ----------------------------
-- 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或文件中添加以下配置:

      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引入

      spring:
  config:
    import: classpath:codegen.yml
    

_3. 使用代码生成器

代码生成器会自动注册到您的Spring Boot应用中,您可以通过以下方式使用:

_3.1 注入代码生成服务

      @Resource
private CodegenService codegenService;

@Resource
private GenConfigService genConfigService;

@Resource
private CodegenProperties codegenProperties;
    

_3.2 获取数据库表列表

可通过以下接口获取所有数据库列表

      @Operation(summary = "获取数据表分页列表")
@GetMapping("/table/page")
public PageResultUtils<TablePageVO> getTablePage(TablePageQuery queryParams) {

    Page<TablePageVO> result = codegenService.getTablePage(queryParams);
    return PageResultUtils.success(result);
}
    

_3.3 获取代码生成配置

获取指定表的配置

      @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 修改代码生成配置

      @Operation(summary = "修改代码生成配置")
@PostMapping("/{tableName}/config")
public BaseResponse<Boolean> saveGenConfig(@PathVariable String tableName, @RequestBody GenConfigForm formData) {
  formData.setTableName(tableName);
  return genConfigService.saveGenConfig(formData);
}
    

示例配置如下

      {
  "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 删除代码生成配置

      @Operation(summary = "删除代码生成配置")
@DeleteMapping("/{tableName}/config")
public BaseResponse<Boolean> deleteGenConfig(
        @Parameter(description = "表名") @PathVariable String tableName) 
{

    return genConfigService.deleteGenConfig(tableName);
}
    

_3.6预览生成的代码

      @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指定的路径

      @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 下载生成的代码压缩包

      @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.vmservice.java.vm
  3. 在配置中指定模板目录:liyao.codegen.template-dir=/templates/codegen

模板文件中可以使用以下变量:

  • ${packageName}: 包名
  • ${moduleName}: 模块名
  • ${subpackageName}: 子包名(tree模式专属)
  • ${entityName}: 实体类名
  • ${tableName}: 表名
  • ${businessName}: 表备注
  • ${author}: 作者
  • ${fieldConfigs}: 字段配置列表

字段配置

代码生成器支持对每个字段进行详细配置:

  • 字段名称: 数据库字段名

  • 字段类型: Java类型,如String、Integer等

  • 字段注释: 字段说明

  • 是否必填: 是否为必填字段

  • 是否在列表显示: 是否在列表页面显示

  • 是否在表单显示: 是否在表单页面显示

  • 是否为查询条件: 是否作为查询条件

  • 查询方式: 等于、模糊查询、大于、小于等

          // 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%'");
        
  • 表单类型: 输入框、下拉框、日期选择器等

          // 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排除不需要生成代码的表:

      liyao:
  codegen:
    exclude-tables:
      - sys_user
      - sys_role
    

自定义输出目录

您可以通过配置liyao.codegen.output-dir自定义代码输出目录:

      liyao:
  codegen:
    output-dir: generated-code
    

声明

作者: liyao

版权:本博客所有文章除特别声明外,均采用CCBY-NC-SA4.O许可协议。转载请注明!

最后更新于 2025-09-30 20:31 history