Skip to content

代码生成设计

1. 概述

ZsAdmin 提供强大的代码生成功能,支持一键生成前后端 CRUD 代码,包括实体类、Mapper、Service、Controller、前端页面等,大幅提高开发效率。本文档将详细介绍后端代码生成的设计与实现。

2. 技术选型

技术版本用途
Velocity2.x模板引擎
MyBatis Plus3.5.xORM 框架
Spring Boot3.x后端框架
Vue 33.x前端框架
Arco Design Vue2.xUI 组件库

3. 代码生成架构

3.1 核心组件

  • CodeGenerator:代码生成器主类
  • TemplateEngine:模板引擎
  • VelocityTemplateEngine:Velocity 模板引擎实现
  • GeneratorConfig:生成配置
  • TableInfo:表信息
  • ColumnInfo:列信息

3.2 架构图

mermaid
graph TD
A[用户操作] --> B[CodeGeneratorController]
B --> C[CodeGeneratorService]
C --> D[DatabaseService]
D --> E[获取表信息]
E --> F[TableInfo]
F --> G[获取列信息]
G --> H[ColumnInfo]
C --> I[TemplateEngine]
I --> J[VelocityTemplateEngine]
J --> K{生成类型}
K --> |实体类| L[Entity Template]
K --> |Mapper| M[Mapper Template]
K --> |Service| N[Service Template]
K --> |Controller| O[Controller Template]
K --> |前端页面| P[Vue Template]
L --> Q[生成 Java 代码]
M --> Q
N --> Q
O --> Q
P --> R[生成 Vue 代码]
Q --> S[输出到指定目录]
R --> S

4. 核心实现

4.1 代码生成器配置

java
@Data
public class GeneratorConfig {
    /**
     * 数据库表名
     */
    private String tableName;
    
    /**
     * 包名
     */
    private String packageName;
    
    /**
     * 模块名
     */
    private String moduleName;
    
    /**
     * 作者
     */
    private String author;
    
    /**
     * 生成类型:单表、树表、主子表
     */
    private String generateType;
    
    /**
     * 是否生成前端代码
     */
    private Boolean generateFrontend;
    
    /**
     * 是否生成 Swagger 文档
     */
    private Boolean generateSwagger;
    
    /**
     * 生成路径
     */
    private String outputPath;
}

4.2 代码生成器主类

java
@Component
public class CodeGenerator {
    @Autowired
    private DatabaseService databaseService;
    
    @Autowired
    private VelocityTemplateEngine velocityTemplateEngine;
    
    public void generate(GeneratorConfig config) {
        // 获取表信息
        TableInfo tableInfo = databaseService.getTableInfo(config.getTableName());
        
        // 获取列信息
        List<ColumnInfo> columnInfos = databaseService.getColumnInfos(config.getTableName());
        
        // 构建数据模型
        Map<String, Object> dataModel = buildDataModel(config, tableInfo, columnInfos);
        
        // 生成代码
        generateCode(dataModel, config);
    }
    
    private Map<String, Object> buildDataModel(GeneratorConfig config, TableInfo tableInfo, List<ColumnInfo> columnInfos) {
        // 构建数据模型
        Map<String, Object> dataModel = new HashMap<>();
        dataModel.put("config", config);
        dataModel.put("tableInfo", tableInfo);
        dataModel.put("columnInfos", columnInfos);
        dataModel.put("now", new Date());
        return dataModel;
    }
    
    private void generateCode(Map<String, Object> dataModel, GeneratorConfig config) {
        // 生成实体类
        velocityTemplateEngine.generate("entity.java.vm", dataModel, config.getOutputPath() + "/entity/");
        
        // 生成 Mapper
        velocityTemplateEngine.generate("mapper.java.vm", dataModel, config.getOutputPath() + "/mapper/");
        
        // 生成 Service
        velocityTemplateEngine.generate("service.java.vm", dataModel, config.getOutputPath() + "/service/");
        
        // 生成 Controller
        velocityTemplateEngine.generate("controller.java.vm", dataModel, config.getOutputPath() + "/controller/");
        
        // 生成前端代码
        if (config.getGenerateFrontend()) {
            generateFrontendCode(dataModel, config);
        }
    }
    
    private void generateFrontendCode(Map<String, Object> dataModel, GeneratorConfig config) {
        // 生成 Vue 页面
        velocityTemplateEngine.generate("vue/index.vue.vm", dataModel, config.getOutputPath() + "/vue/");
        
        // 生成 API 调用
        velocityTemplateEngine.generate("vue/api.js.vm", dataModel, config.getOutputPath() + "/vue/");
        
        // 生成路由配置
        velocityTemplateEngine.generate("vue/router.js.vm", dataModel, config.getOutputPath() + "/vue/");
    }
}

4.3 数据库服务

java
@Service
public class DatabaseService {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    public TableInfo getTableInfo(String tableName) {
        // 查询表信息
        String sql = "SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ? AND TABLE_SCHEMA = DATABASE()";
        return jdbcTemplate.queryForObject(sql, new Object[]{tableName}, (rs, rowNum) -> {
            TableInfo tableInfo = new TableInfo();
            tableInfo.setTableName(rs.getString("TABLE_NAME"));
            tableInfo.setTableComment(rs.getString("TABLE_COMMENT"));
            return tableInfo;
        });
    }
    
    public List<ColumnInfo> getColumnInfos(String tableName) {
        // 查询列信息
        String sql = "SELECT COLUMN_NAME, COLUMN_TYPE, DATA_TYPE, COLUMN_COMMENT, IS_NULLABLE, COLUMN_KEY, COLUMN_DEFAULT " +
                     "FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = DATABASE()";
        return jdbcTemplate.query(sql, new Object[]{tableName}, (rs, rowNum) -> {
            ColumnInfo columnInfo = new ColumnInfo();
            columnInfo.setColumnName(rs.getString("COLUMN_NAME"));
            columnInfo.setColumnType(rs.getString("COLUMN_TYPE"));
            columnInfo.setDataType(rs.getString("DATA_TYPE"));
            columnInfo.setColumnComment(rs.getString("COLUMN_COMMENT"));
            columnInfo.setIsNullable(rs.getString("IS_NULLABLE"));
            columnInfo.setColumnKey(rs.getString("COLUMN_KEY"));
            columnInfo.setColumnDefault(rs.getString("COLUMN_DEFAULT"));
            return columnInfo;
        });
    }
}

5. 代码生成功能

5.1 生成类型

  • 单表:生成单表 CRUD 代码
  • 树表:生成树表 CRUD 代码,支持树形结构
  • 主子表:生成主子表 CRUD 代码,支持主子表关联

5.2 生成内容

后端代码

  • 实体类:包含字段、getter/setter、toString 等
  • Mapper 接口:包含基本的 CRUD 方法
  • Mapper XML:包含 SQL 语句
  • Service 接口:包含业务逻辑接口
  • Service 实现:包含业务逻辑实现
  • Controller:包含 RESTful API
  • Swagger 文档:自动生成 API 文档

前端代码

  • Vue 页面:包含列表、表单、详情等页面
  • API 调用:包含与后端交互的 API
  • 路由配置:包含路由定义
  • 组件:包含自定义组件

5.3 配置选项

  • 包名配置
  • 模块名配置
  • 作者配置
  • 生成类型选择
  • 前端代码生成开关
  • Swagger 文档生成开关
  • 生成路径配置

6. 最佳实践

6.1 数据库设计规范

  • 表名使用下划线命名,如 sys_user
  • 字段名使用下划线命名,如 user_name
  • 每个表必须有 id 主键
  • 包含 create_bycreate_timeupdate_byupdate_time 字段
  • 表和字段必须有注释

6.2 代码生成规范

  • 生成的代码应符合项目的代码规范
  • 生成的代码应包含适当的注释
  • 生成的代码应易于维护和扩展
  • 生成的代码应遵循 SOLID 原则

6.3 使用建议

  • 先设计数据库表,再生成代码
  • 生成代码后,根据业务需求进行调整
  • 不要直接修改生成的代码,应通过继承或扩展的方式进行修改
  • 定期更新模板,适应项目的代码规范变化

7. 扩展功能

7.1 自定义模板

  • 支持自定义 Velocity 模板
  • 支持根据项目需求调整模板
  • 支持模板版本管理

7.2 批量生成

  • 支持批量生成多张表的代码
  • 支持生成整个模块的代码
  • 支持生成整个项目的代码

7.3 集成开发工具

  • 支持 IDEA 插件
  • 支持 VS Code 插件
  • 支持 Eclipse 插件

8. 性能优化

  • 缓存表信息,避免重复查询数据库
  • 异步生成代码,提高用户体验
  • 支持增量生成,只生成修改的代码
  • 模板预编译,提高生成速度