Skip to content

用于生成前端和后端的代码,生成步骤:

  • [写SQL创表]
  • [配置数据源]
  • [导入表结构]
  • [配置生成信息]
  • [配置字段信息]
  • [预览]
  • [本地生成或远程下载]

写SQL创表

请参考[数据库设计]

配置数据源

详细参考: [数据源维护]

导入表结构

将需要生成的表,导入代码生成器。导入时,会读取数据库表结构的元数据,将表名、注释、字段名、字段注释、字段类型、字段长度、不能为空、是否主键等关键的表信息读取出来,存入代码生成表。

导入表结构时,会根据application.yml中配置的信息存储一些默认值,具体如下:

yaml
# 代码生成
acuity:
  generator:
  	# 后端生成路径
    outputDir: /Users/acuity/gitlab/acuity-cloud-pro-datasource-column
    # 前端生成路径
    frontOutputDir: /Users/acuity/gitlab/acuity-web-pro
    # 作者
    author: acuity
    # 表名转换为实体类类名时,是否去除表名前缀
    tablePrefix:
      - xxx_
    # 字段名转换为实体类字段名时,是否去除字段前缀
    fieldPrefix:
      - xxx_
    # 字段名转换为实体类字段名时,是否去除字段后缀
    fieldSuffix:
      - xxx_
    # 项目前缀
    projectPrefix: 'acuity'
    # 父类
    superClass: SUPER_CLASS
    packageInfoConfig: # 其他配置建议保持PackageInfoConfig中的默认值
      # 生成代码位于 src/main/java 下的基础包
      parent: 'top.acuity.box'
      # acuity-util 项目的基础包
      utilParent: 'top.acuity.commons'
      # 枚举 位于 src/main/java/{parent}/{moduleName} 下的 包名
      enumeration: 'enumeration'
      # saveVO 位于 src/main/java/{parent}/{moduleName} 下的 包名
      saveVo: 'vo.save'
      # updateVO 位于 src/main/java/{parent}/{moduleName} 下的 包名
      updateVo: 'vo.update'
      # query 位于 src/main/java/{parent}/{moduleName} 下的 包名
      pageQuery: 'vo.query'
      # resultVo src/main/java/{parent}/{moduleName} 下的 包名
      resultVo: 'vo.result'
      # 实体 位于 src/main/java/{parent}/{moduleName} 下的 包名
      entity: 'entity'
      # manager 位于 src/main/java/{parent}/{moduleName} 下的 包名
      manager: 'manager'
      # managerImpl 位于 src/main/java/{parent}/{moduleName} 下的 包名
      managerImpl: 'manager.{}impl'
      # service 位于 src/main/java/{parent}/{moduleName} 下的 包名
      service: 'service'
      # serviceImpl 位于 src/main/java/{parent}/{moduleName} 下的 包名
      serviceImpl: 'service.{}impl'
      # controller 位于 src/main/java/{parent}/{moduleName} 下的 包名
      controller: 'controller'
      # mapper 位于 src/main/java/{parent}/{moduleName} 下的 包名
      mapper: 'mapper'
      # Mapper XML 位于 src/main/resource 下的 包名
      xml: 'mapper_{}/base'
    entity-config:   # 实体类配置
      # 【实体、VO】时间类型对应策略  ONLY_DATE: java.util  SQL_PACK:java.sql  TIME_PACK: java.time
      dateType: TIME_PACK
      # 【实体】Entity类的父类
      entitySuperClass: ENTITY
      # 【实体】指定生成的主键的ID类型 (${superClass} == NONE 时,新生成的实体才生效)
      idType: INPUT
      # 【实体、VO】表字段转换为实体字段的命名策略
      columnNaming: underline_to_camel
      # 【实体、VO】生成实体类时,忽略的字段(字段名)
		  ignoreColumns:
        - xxx
      # 【实体】 是否生成字段常量
      columnConstant: false
      # 【实体、VO】是否为链式模型
      chain: true
      # 【实体、VO】 是否为lombok模型
      lombok: true
      # 【实体】乐观锁字段名称
      versionColumnName: ''
      # 【实体】乐观锁属性名称
      versionPropertyName: ''
      # 【实体】逻辑删除字段名称
      logicDeleteColumnName: ''
      # 【实体】逻辑删除属性名称
      logicDeletePropertyName: ''
      # 【实体】生成的@TableField注解上需要填充的字段和填充类型
      fillColumnName:
        - xxx: INSERT
      # 【VO】格式化SaveVO文件名称
      formatSaveVoFileName: ''
      # 【VO】格式化UpdateVO文件名称
      formatUpdateVoFileName: ''
      # 【VO】格式化ResultVO文件名称
      formatResultVoFileName: ''
      # 【VO】格式化 PageQuery 文件名称
      formatPageQueryFileName: ''
    mapperConfig:   # mapper类配置
   		# 格式化Mapper文件名称
      formatMapperFileName: ''
      # 格式化Xml文件名称
      formatXmlFileName: ''
      # 是否添加 @Mapper 注解(默认 false)
      mapperAnnotation: false
      # mapper类上是否添加忽略表结构 @InterceptorIgnore
      columnAnnotationTablePrefix:
        - 表的前缀
      # 生成的xml中,是否包含BaseResultMap(默认 false)  
      baseResultMap: true
    serviceConfig:
      # 继承的Service类全称,带包名
      superServiceClass: top.acuity.commons.base.service.SuperService
      # 继承的ServiceImpl类全称,带包名
      superServiceImplClass: top.acuity.commons.base.service.impl.SuperServiceImpl
      # 格式化service接口文件名称
      formatServiceFileName: '{}Service'
      # 格式化service实现类文件名称
      formatServiceImplFileName: ''
      # 匹配到此前缀的表,生成的 serviceImpl 类上会自动添加切换数据源注解 @DS
      dsTablePrefix: 
      	- xxx
    managerConfig:
      # 继承的Manager类全称,带包名
      superManagerClass: 'top.acuity.commons.base.manager.SuperManager'
      # 继承的ManagerImpl类全称,带包名
      superManagerImplClass: 'top.acuity.commons.base.manager.impl.SuperManagerImpl'
      # 格式化Manager接口文件名称
      formatManagerFileName: ''
      # 格式化Manager实现类文件名称
      formatManagerImplFileName: ''
    controllerConfig:
    	# 生成 @RestController 控制器(默认 false)
      restStyle: true
      # 格式化文件名称
      formatFileName: ''
      # 驼峰转连字符
      hyphenStyle: false  
      # 继承的Controller类全称,带包名
      superClass: 'top.acuity.commons.base.controller.SuperController'
    webProConfig:
    	# 格式化菜单文件名称
      formatMenuName: {}维护
      # 前端生成页面样式模板
      tpl: SIMPLE
    fileOverrideStrategy:  # 文件覆盖策略
      entityFileOverride: OVERRIDE
      sqlFileOverride: OVERRIDE
      mapperFileOverride: EXIST_IGNORE
      xmlFileOverride: OVERRIDE
      managerFileOverride: EXIST_IGNORE
      serviceFileOverride: EXIST_IGNORE
      controllerFileOverride: EXIST_IGNORE
      apiModelFileOverride: OVERRIDE
      langFileOverride: OVERRIDE
      indexEditTreeFileOverride: EXIST_IGNORE
      dataFileOverride: EXIST_IGNORE
    constantsPackage:   # 公共枚举的完整类名,配置后自定义的枚举类才能正常 import
      # 业务服务 后台手动改动过的枚举
      FieldFill: com.baomidou.mybatisplus.annotation.FieldFill
      SuperClassEnum: top.acuity.box.generator.enumeration.SuperClassEnum
      EntitySuperClassEnum: top.acuity.box.generator.enumeration.EntitySuperClassEnum
      # common 常量
      EchoDictType: top.acuity.box.model.constant.EchoDictType
      EchoApi: top.acuity.box.model.constant.EchoApi
      # common 公共枚举
      HttpMethod: top.acuity.box.model.enumeration.HttpMethod
      BooleanEnum: top.acuity.box.model.enumeration.BooleanEnum
      StateEnum: top.acuity.box.model.enumeration.StateEnum
      UserStatusEnum: top.acuity.box.model.enumeration.base.UserStatusEnum
      RoleCategoryEnum: top.acuity.box.model.enumeration.base.RoleCategoryEnum
      ActiveStatusEnum: top.acuity.box.model.enumeration.base.ActiveStatusEnum
      OrgTypeEnum: top.acuity.box.model.enumeration.base.OrgTypeEnum
      FileType: top.acuity.box.model.enumeration.base.FileType
      DateType: top.acuity.box.model.enumeration.base.DateType
      DictClassifyEnum: top.acuity.box.model.enumeration.system.DictClassifyEnum
      DefTenantStatusEnum: top.acuity.box.model.enumeration.system.DefTenantStatusEnum
      DataTypeEnum: top.acuity.box.model.enumeration.system.DataTypeEnum
      TenantConnectTypeEnum: top.acuity.box.model.enumeration.system.TenantConnectTypeEnum
# 代码生成
acuity:
  generator:
  	# 后端生成路径
    outputDir: /Users/acuity/gitlab/acuity-cloud-pro-datasource-column
    # 前端生成路径
    frontOutputDir: /Users/acuity/gitlab/acuity-web-pro
    # 作者
    author: acuity
    # 表名转换为实体类类名时,是否去除表名前缀
    tablePrefix:
      - xxx_
    # 字段名转换为实体类字段名时,是否去除字段前缀
    fieldPrefix:
      - xxx_
    # 字段名转换为实体类字段名时,是否去除字段后缀
    fieldSuffix:
      - xxx_
    # 项目前缀
    projectPrefix: 'acuity'
    # 父类
    superClass: SUPER_CLASS
    packageInfoConfig: # 其他配置建议保持PackageInfoConfig中的默认值
      # 生成代码位于 src/main/java 下的基础包
      parent: 'top.acuity.box'
      # acuity-util 项目的基础包
      utilParent: 'top.acuity.commons'
      # 枚举 位于 src/main/java/{parent}/{moduleName} 下的 包名
      enumeration: 'enumeration'
      # saveVO 位于 src/main/java/{parent}/{moduleName} 下的 包名
      saveVo: 'vo.save'
      # updateVO 位于 src/main/java/{parent}/{moduleName} 下的 包名
      updateVo: 'vo.update'
      # query 位于 src/main/java/{parent}/{moduleName} 下的 包名
      pageQuery: 'vo.query'
      # resultVo src/main/java/{parent}/{moduleName} 下的 包名
      resultVo: 'vo.result'
      # 实体 位于 src/main/java/{parent}/{moduleName} 下的 包名
      entity: 'entity'
      # manager 位于 src/main/java/{parent}/{moduleName} 下的 包名
      manager: 'manager'
      # managerImpl 位于 src/main/java/{parent}/{moduleName} 下的 包名
      managerImpl: 'manager.{}impl'
      # service 位于 src/main/java/{parent}/{moduleName} 下的 包名
      service: 'service'
      # serviceImpl 位于 src/main/java/{parent}/{moduleName} 下的 包名
      serviceImpl: 'service.{}impl'
      # controller 位于 src/main/java/{parent}/{moduleName} 下的 包名
      controller: 'controller'
      # mapper 位于 src/main/java/{parent}/{moduleName} 下的 包名
      mapper: 'mapper'
      # Mapper XML 位于 src/main/resource 下的 包名
      xml: 'mapper_{}/base'
    entity-config:   # 实体类配置
      # 【实体、VO】时间类型对应策略  ONLY_DATE: java.util  SQL_PACK:java.sql  TIME_PACK: java.time
      dateType: TIME_PACK
      # 【实体】Entity类的父类
      entitySuperClass: ENTITY
      # 【实体】指定生成的主键的ID类型 (${superClass} == NONE 时,新生成的实体才生效)
      idType: INPUT
      # 【实体、VO】表字段转换为实体字段的命名策略
      columnNaming: underline_to_camel
      # 【实体、VO】生成实体类时,忽略的字段(字段名)
		  ignoreColumns:
        - xxx
      # 【实体】 是否生成字段常量
      columnConstant: false
      # 【实体、VO】是否为链式模型
      chain: true
      # 【实体、VO】 是否为lombok模型
      lombok: true
      # 【实体】乐观锁字段名称
      versionColumnName: ''
      # 【实体】乐观锁属性名称
      versionPropertyName: ''
      # 【实体】逻辑删除字段名称
      logicDeleteColumnName: ''
      # 【实体】逻辑删除属性名称
      logicDeletePropertyName: ''
      # 【实体】生成的@TableField注解上需要填充的字段和填充类型
      fillColumnName:
        - xxx: INSERT
      # 【VO】格式化SaveVO文件名称
      formatSaveVoFileName: ''
      # 【VO】格式化UpdateVO文件名称
      formatUpdateVoFileName: ''
      # 【VO】格式化ResultVO文件名称
      formatResultVoFileName: ''
      # 【VO】格式化 PageQuery 文件名称
      formatPageQueryFileName: ''
    mapperConfig:   # mapper类配置
   		# 格式化Mapper文件名称
      formatMapperFileName: ''
      # 格式化Xml文件名称
      formatXmlFileName: ''
      # 是否添加 @Mapper 注解(默认 false)
      mapperAnnotation: false
      # mapper类上是否添加忽略表结构 @InterceptorIgnore
      columnAnnotationTablePrefix:
        - 表的前缀
      # 生成的xml中,是否包含BaseResultMap(默认 false)  
      baseResultMap: true
    serviceConfig:
      # 继承的Service类全称,带包名
      superServiceClass: top.acuity.commons.base.service.SuperService
      # 继承的ServiceImpl类全称,带包名
      superServiceImplClass: top.acuity.commons.base.service.impl.SuperServiceImpl
      # 格式化service接口文件名称
      formatServiceFileName: '{}Service'
      # 格式化service实现类文件名称
      formatServiceImplFileName: ''
      # 匹配到此前缀的表,生成的 serviceImpl 类上会自动添加切换数据源注解 @DS
      dsTablePrefix: 
      	- xxx
    managerConfig:
      # 继承的Manager类全称,带包名
      superManagerClass: 'top.acuity.commons.base.manager.SuperManager'
      # 继承的ManagerImpl类全称,带包名
      superManagerImplClass: 'top.acuity.commons.base.manager.impl.SuperManagerImpl'
      # 格式化Manager接口文件名称
      formatManagerFileName: ''
      # 格式化Manager实现类文件名称
      formatManagerImplFileName: ''
    controllerConfig:
    	# 生成 @RestController 控制器(默认 false)
      restStyle: true
      # 格式化文件名称
      formatFileName: ''
      # 驼峰转连字符
      hyphenStyle: false  
      # 继承的Controller类全称,带包名
      superClass: 'top.acuity.commons.base.controller.SuperController'
    webProConfig:
    	# 格式化菜单文件名称
      formatMenuName: {}维护
      # 前端生成页面样式模板
      tpl: SIMPLE
    fileOverrideStrategy:  # 文件覆盖策略
      entityFileOverride: OVERRIDE
      sqlFileOverride: OVERRIDE
      mapperFileOverride: EXIST_IGNORE
      xmlFileOverride: OVERRIDE
      managerFileOverride: EXIST_IGNORE
      serviceFileOverride: EXIST_IGNORE
      controllerFileOverride: EXIST_IGNORE
      apiModelFileOverride: OVERRIDE
      langFileOverride: OVERRIDE
      indexEditTreeFileOverride: EXIST_IGNORE
      dataFileOverride: EXIST_IGNORE
    constantsPackage:   # 公共枚举的完整类名,配置后自定义的枚举类才能正常 import
      # 业务服务 后台手动改动过的枚举
      FieldFill: com.baomidou.mybatisplus.annotation.FieldFill
      SuperClassEnum: top.acuity.box.generator.enumeration.SuperClassEnum
      EntitySuperClassEnum: top.acuity.box.generator.enumeration.EntitySuperClassEnum
      # common 常量
      EchoDictType: top.acuity.box.model.constant.EchoDictType
      EchoApi: top.acuity.box.model.constant.EchoApi
      # common 公共枚举
      HttpMethod: top.acuity.box.model.enumeration.HttpMethod
      BooleanEnum: top.acuity.box.model.enumeration.BooleanEnum
      StateEnum: top.acuity.box.model.enumeration.StateEnum
      UserStatusEnum: top.acuity.box.model.enumeration.base.UserStatusEnum
      RoleCategoryEnum: top.acuity.box.model.enumeration.base.RoleCategoryEnum
      ActiveStatusEnum: top.acuity.box.model.enumeration.base.ActiveStatusEnum
      OrgTypeEnum: top.acuity.box.model.enumeration.base.OrgTypeEnum
      FileType: top.acuity.box.model.enumeration.base.FileType
      DateType: top.acuity.box.model.enumeration.base.DateType
      DictClassifyEnum: top.acuity.box.model.enumeration.system.DictClassifyEnum
      DefTenantStatusEnum: top.acuity.box.model.enumeration.system.DefTenantStatusEnum
      DataTypeEnum: top.acuity.box.model.enumeration.system.DataTypeEnum
      TenantConnectTypeEnum: top.acuity.box.model.enumeration.system.TenantConnectTypeEnum

配置生成信息

用于配置生成的代码存放路径、文件名、代码结构等信息。

  1. 服务名
    • 确保前端ServicePrefixEnum中的枚举值KEY 与 后端“服务名”和acuity-gateway-server.yml中“uri”保持一致
    • 确保前端ServicePrefixEnum中的枚举值VALUE 与 后端acuity-gateway-server.yml中“predicates”配置一致
    • 如: acuity-base、acuity-base-api、acuity-base-biz、acuity-base-controller、acuity-base-server 中的 base
    • 如: acuity-system-server 中的 system
  2. 父包名 生成业务代码的基础包包名。如:"top.acuity.box.base.dao.common" 中的 "top.acuity.box"
  3. 模块名 建议跟{服务名一致}保持一致。如:
    • "top.acuity.box.base.dao.common" 中的 "base"
    • "top.acuity.box.file.dao" 中的 "file"
  4. 子包名
    • "top.acuity.box.base.dao.common" 中的 "common"
    • "top.acuity.box.base.dao.system" 中的 "system"
  5. 实体父类 实体类需要继承谁,参考:EntitySuperClassEnum
  6. 父类 Controller、Service、Manager、Mapper类需要继承谁,参考:SuperClassEnum
  7. @DS ServiceImpl类是否标记@DS注解,加上该注解后,sql操作会自动切换数据源。 datasource模式才会使用该参数,column、none模式请忽略。
  8. 数据源 @DS选是,ServiceImpl类标记的@DS注解具体值
  9. @TenantLine Mapper类是否标记@TenantLine注解,加上该注解sql操作不会自动拼接租户ID。 column模式才会使用该参数,datasource、none模式请忽略。
  10. lombok 实体类是否使用Lombok注解
  11. 链式模型 实体类是否使用@Accessors(chain = true)注解
  12. 生成字段常量 实体类中是否生成字段常量
  13. 后端生成路径
  14. 前端生成路径
  15. 前端应用名
    • src/views/ 目录下的 basic 或 devOperation 或 其他
    • src/api/ 目录下的 basic 或 devOperation 或 其他
    • src/locales/lang/{语言}/ 目录下的 basic 或 devOperation 或 其他
    • 其他 表示其他应用
  16. 前端模块名
    • src/api/{前端应用名} 目录下的文件夹名
    • src/views/{前端应用名} 目录下的文件夹名
    • src/locales/lang/{语言}/{前端应用名} 目录下的文件夹名
    • 如: src/views/devOperation/ 下的 application、developer 等目录
    • 如: src/api/devOperation/ 下的 application、developer 等目录
  17. 弹窗方式 前端代码index.vue页面点击新增或编辑时,弹窗的打开方式
  18. 生成模板 前端代码生成何种操作风格的页面
  19. 显示??按钮 生成的前端页面,是否包含新增、编辑、删除、复制、详情等按钮
  20. ??按钮权限 生成的前端页面,新增、编辑、删除、复制、详情等按钮是否控制按钮权限
  21. 菜单所属应用 当前功能生成后,菜单属于哪个应用?
  22. 上级菜单 当前功能生成后,显示在左侧菜单的位置
  23. 当前菜单名 当前功能生成后,显示在左侧的菜单名
  24. 菜单图标 当前功能生成后,显示在左侧的菜单图标

配置字段信息

用于配置生成的实体类字段的信息,默认值来源于=导入=时,读取表结构元数据信息。

  1. 列名称 字段的原始名称 提示

    “原始”的意思是,数据库表结构中是什么这里就存什么。

  2. 列类型 字段的原始数据库类型

  3. 列描述 字段的原始注释。在生成代码时,会将列描述生成到字段的注释中。

  4. 文档描述 体现在Swagger注解上的注释。=导入=时,将=列描述=截取 ;前的字符作为 =文档描述= 。实现代码:

    java
    /**
     * @param comment 列描述
     */
    private static String getSwaggerComment(String comment) {
        String swaggerComment = StrUtil.isBlank(comment) ? StrUtil.EMPTY : StrUtil.trim(comment);
        if (swaggerComment.contains(StrPool.SEMICOLON)) {
            swaggerComment = StrUtil.subBefore(swaggerComment, StrPool.SEMICOLON, false);
        }
        // 若含有换行符,替换为空格
      	// \n 是mysql注释中的换行符,其他数据库的换行符需要自己改这里代码适配下
        swaggerComment = StrUtil.replace(swaggerComment, "\n", " ");
        return swaggerComment;
    }
    /**
     * @param comment 列描述
     */
    private static String getSwaggerComment(String comment) {
        String swaggerComment = StrUtil.isBlank(comment) ? StrUtil.EMPTY : StrUtil.trim(comment);
        if (swaggerComment.contains(StrPool.SEMICOLON)) {
            swaggerComment = StrUtil.subBefore(swaggerComment, StrPool.SEMICOLON, false);
        }
        // 若含有换行符,替换为空格
      	// \n 是mysql注释中的换行符,其他数据库的换行符需要自己改这里代码适配下
        swaggerComment = StrUtil.replace(swaggerComment, "\n", " ");
        return swaggerComment;
    }
  5. JAVA类型 根据=列类型=自动映射的Java字段类型。

    java
    public static DefGenTableColumn initColumnField(GeneratorConfig generatorConfig, DbType dbType, DefGenTable genTable, Column column) {
        ITypeConvert typeConvert = TypeConverts.getTypeConvert(dbType);
        ColumnType columnType = typeConvert.processTypeConvert(entityConfig.getDateType(), column.getTypeName(), column.getSize(), column.getDigit());
    
      	// JAVA类型
      	tableColumn.setJavaType(columnType.getType());
      	// TS类型
        tableColumn.setTsType(columnType.getTsType());
    }
    public static DefGenTableColumn initColumnField(GeneratorConfig generatorConfig, DbType dbType, DefGenTable genTable, Column column) {
        ITypeConvert typeConvert = TypeConverts.getTypeConvert(dbType);
        ColumnType columnType = typeConvert.processTypeConvert(entityConfig.getDateType(), column.getTypeName(), column.getSize(), column.getDigit());
    
      	// JAVA类型
      	tableColumn.setJavaType(columnType.getType());
      	// TS类型
        tableColumn.setTsType(columnType.getTsType());
    }
  6. TS类型 根据=列类型=按照一定的规则转换为前端TS语法类型。

  7. JAVA字段名 根据=列名称=按照一定的规则转换为Java实体类和VO类的字段名。

    java
    /**
     * @param name     列名称
     * @param strategy 策略
     * @param prefix   前缀
     * @param suffix   后缀
     * @return java.lang.String
     * @date 2023/4/16 10:45 PM
     */
    private static String processName(String name, NamingStrategy strategy, List<String> prefix, List<String> suffix) {
        String propertyName = name;
        // 删除前缀
        if (prefix.size() > 0) {
            propertyName = NamingStrategy.removePrefix(propertyName, prefix);
        }
        // 删除后缀
        if (suffix.size() > 0) {
            propertyName = NamingStrategy.removeSuffix(propertyName, suffix);
        }
        if (StringUtils.isBlank(propertyName)) {
            throw new RuntimeException(String.format("%s 的名称转换结果为空,请检查是否配置问题", name));
        }
        // 下划线转驼峰
        if (NamingStrategy.underline_to_camel.equals(strategy)) {
            return NamingStrategy.underlineToCamel(propertyName);
        }
        return propertyName;
    }
    /**
     * @param name     列名称
     * @param strategy 策略
     * @param prefix   前缀
     * @param suffix   后缀
     * @return java.lang.String
     * @date 2023/4/16 10:45 PM
     */
    private static String processName(String name, NamingStrategy strategy, List<String> prefix, List<String> suffix) {
        String propertyName = name;
        // 删除前缀
        if (prefix.size() > 0) {
            propertyName = NamingStrategy.removePrefix(propertyName, prefix);
        }
        // 删除后缀
        if (suffix.size() > 0) {
            propertyName = NamingStrategy.removeSuffix(propertyName, suffix);
        }
        if (StringUtils.isBlank(propertyName)) {
            throw new RuntimeException(String.format("%s 的名称转换结果为空,请检查是否配置问题", name));
        }
        // 下划线转驼峰
        if (NamingStrategy.underline_to_camel.equals(strategy)) {
            return NamingStrategy.underlineToCamel(propertyName);
        }
        return propertyName;
    }
  8. 必填

  9. 长度 字段长度。字符串类型、SHORT、BYTE,会自动在SaveVO、UpdateVO的字段上标记 @Size(max={长度}) 注解用于表单校验。

    html
    <!-- saveVO.java.ftl、updateVO.java.ftl -->
    <#if field.javaType == "String">
    @Size(max = ${field.size?string("##0")}, message = "${field.swaggerComment!}长度不能超过${r'{max}'}")
    <#else>
        <#if field.type?upper_case?starts_with("SHORT")>
    @Size(min = Short.MIN_VALUE, max = Short.MAX_VALUE, message = "${field.customMap.fieldComment!}大小不能超过${r'{max}'}")
        </#if>
        <#if field.type?upper_case?starts_with("BYTE")>
    @Size(min = Byte.MIN_VALUE, max = Byte.MAX_VALUE, message = "${field.customMap.fieldComment!}大小不能超过${r'{max}'}")
        </#if>
    </#if>
    private ${field.javaType} ${field.javaField};
    <!-- saveVO.java.ftl、updateVO.java.ftl -->
    <#if field.javaType == "String">
    @Size(max = ${field.size?string("##0")}, message = "${field.swaggerComment!}长度不能超过${r'{max}'}")
    <#else>
        <#if field.type?upper_case?starts_with("SHORT")>
    @Size(min = Short.MIN_VALUE, max = Short.MAX_VALUE, message = "${field.customMap.fieldComment!}大小不能超过${r'{max}'}")
        </#if>
        <#if field.type?upper_case?starts_with("BYTE")>
    @Size(min = Byte.MIN_VALUE, max = Byte.MAX_VALUE, message = "${field.customMap.fieldComment!}大小不能超过${r'{max}'}")
        </#if>
    </#if>
    private ${field.javaType} ${field.javaField};
  10. 主键 生成代码时,该字段是否为注解。

    html
    <!-- entity.java.ftl -->
    
    <#list fields as field>
        /**
         * ${field.comment!?replace("\n","\n     * ")}
         */
    <#if field.isPk>
        <#-- 
             主键: 使用 @TableId
             自增: type = IdType.AUTO
             -->
        @TableId(value = "${field.name}"<#if field.isIncrement>, type = IdType.AUTO<#elseif entityConfig.idType??>, type = IdType.${entityConfig.idType}</#if>)
    <#else>
        @TableField(value = "${field.name}"<#if field.fill?? && field.fill?trim != ''>, fill = FieldFill.${field.fill}</#if><#if field.queryType?? && field.queryType?trim != ''>, condition = ${field.queryType}<#else></#if>)
    </#if>
    <#-- 乐观锁 -->
    <#if field.isVersionField>
        @Version
    </#if>
    <#-- 逻辑删除 -->
    <#if field.isLogicDeleteField>
        @TableLogic
    </#if>
        private ${field.javaType} ${field.javaField};
    </#list>
    <!-- entity.java.ftl -->
    
    <#list fields as field>
        /**
         * ${field.comment!?replace("\n","\n     * ")}
         */
    <#if field.isPk>
        <#-- 
             主键: 使用 @TableId
             自增: type = IdType.AUTO
             -->
        @TableId(value = "${field.name}"<#if field.isIncrement>, type = IdType.AUTO<#elseif entityConfig.idType??>, type = IdType.${entityConfig.idType}</#if>)
    <#else>
        @TableField(value = "${field.name}"<#if field.fill?? && field.fill?trim != ''>, fill = FieldFill.${field.fill}</#if><#if field.queryType?? && field.queryType?trim != ''>, condition = ${field.queryType}<#else></#if>)
    </#if>
    <#-- 乐观锁 -->
    <#if field.isVersionField>
        @Version
    </#if>
    <#-- 逻辑删除 -->
    <#if field.isLogicDeleteField>
        @TableLogic
    </#if>
        private ${field.javaType} ${field.javaField};
    </#list>

    注意

    若你的实体类已经继承了Entity和SuperEntity,=主键=属性请保持默认值,否则生成的代码可能无法运行。

    因为代码生成器只负责根据模板生成代码,不负责检查代码逻辑是否正确,若由于你配置错误,导致生成出来的代码无法运行,属于正常现象。

  11. 自增 若该字段配置为 =主键= ,还可以配置是否自增。

  12. 逻辑删除 标记该字段是否逻辑删除字段 注意

    代码生成器只负责生成注解,不负责具体的逻辑删除逻辑,请参考mybaits-plus官方文档open in new window配置。

  13. 乐观锁 标记该字段是否乐观锁字段 注意

    代码生成器只负责生成注解,不负责具体的逻辑删除逻辑,请参考mybaits-plus官方文档open in new window配置。

  14. 填充类型 字段的填充类型。参考mybaits-plus文档open in new window@TableField(fill = FieldFill.${field.fill})

  15. 查询方式 可选值: like、eq 。参考mybaits-plus文档open in new window@TableField(condition = ${field.queryType})

  16. 编辑 是否将该字段生成到前端编辑页 表单。

  17. 列表 是否将该字段生成到前端列表页 表格字段。

  18. 查询 是否将该字段生成到前端列表页 查询条件区域。

  19. 宽度 生成的字段在前端表格上显示时的宽度。

  20. 组件 生成的字段在前端表单显示什么组件样式。 参考vben官方文档open in new window

  21. VxeTable组件 生成的字段在前端vxe-table显示什么组件样式。 参考vxe-table官方文档open in new window

  22. Echo 生成的字段如何回显。 importgetEchoTypegetEnumStr

    java
    EchoType echoType = CommentUtils.getEchoType(column.getComment());
    if (echoType != null) {
      	// Echo
        tableColumn.setEchoStr(echoType.getEchoStr());
      	// 字典类型
        tableColumn.setDictType(echoType.getDictType());
    }
    // 解析注释中的枚举类型
    EnumType enumType = CommentUtils.getEnumStr(genTable.getEntityName(), tableColumn.getJavaField(), entityConfig.getFormatEnumFileName(), tableColumn.getSwaggerComment(), column.getComment());
    if (enumType != null) {
        tableColumn.setEnumStr(enumType.getEnumStr());
        tableColumn.setJavaType(enumType.getEnumName());
      	// 枚举类型的回显注解固定值
        tableColumn.setEchoStr("@Echo(api = Echo.ENUM_API)");
        tableColumn.setTsType("string");
    
        tableColumn.setComponent(ComponentEnum.PLUS_API_RADIO_GROUP.getValue());
        tableColumn.setVxeComponent(VxeComponentEnum.$RADIO.getValue());
        tableColumn.setQueryType(SqlConditionEnum.EQUAL);
    }
    EchoType echoType = CommentUtils.getEchoType(column.getComment());
    if (echoType != null) {
      	// Echo
        tableColumn.setEchoStr(echoType.getEchoStr());
      	// 字典类型
        tableColumn.setDictType(echoType.getDictType());
    }
    // 解析注释中的枚举类型
    EnumType enumType = CommentUtils.getEnumStr(genTable.getEntityName(), tableColumn.getJavaField(), entityConfig.getFormatEnumFileName(), tableColumn.getSwaggerComment(), column.getComment());
    if (enumType != null) {
        tableColumn.setEnumStr(enumType.getEnumStr());
        tableColumn.setJavaType(enumType.getEnumName());
      	// 枚举类型的回显注解固定值
        tableColumn.setEchoStr("@Echo(api = Echo.ENUM_API)");
        tableColumn.setTsType("string");
    
        tableColumn.setComponent(ComponentEnum.PLUS_API_RADIO_GROUP.getValue());
        tableColumn.setVxeComponent(VxeComponentEnum.$RADIO.getValue());
        tableColumn.setQueryType(SqlConditionEnum.EQUAL);
    }
  23. 字典类型 生成的字段需要回显,且为字典类型时,配置该字段的枚举类型。

  24. 枚举 生成的字段为枚举类型时,字段注释中的值。

  25. 默认值 显示在前端表单中的默认值。

  26. 提示信息 前端表单中的感叹号提示信息。

  27. 主页提示信息 前端表格的表头上的感叹号提示信息。

预览

根据前面步骤总配置的信息,实时预览生成的前端、后端、SQL语句等代码。

本地生成或远程下载

可以分别生成或下载前端或后端的代码。

生成策略

  • 覆盖 无论是否有同名文件,都覆盖原文件覆盖生成。
  • 新增 若检测到有同名文件,就在同一个文件夹下新增一个文件,文件名后缀为 _new
  • 忽略 无论是否有同名文件,都忽略生成此文件
  • 存在时忽略 检测到同名文件就忽略生成,没有同名文件就立即生成。

欢迎使用天源云Saas快速开发系统