
前言在我们很多业务开发中最基础也是最需要的就是对数据表进行一些CRUD的功能我们根据表创建model、request、query、controller、service、repository等层但这些又是一些重复的事情既然是重复的事情都可以通过工具进行替代下面以JAVA进行简单讲解。一、技术栈Spring Boot 2.3.6.RELEASE MavenFreeMarker 2.3.26-incubating 模板引擎MySQL 8.x用 JdbcTemplate 查询 information_schemaLombokSpringfox Swagger 3.0API 文档生成的代码依赖Spring Data JPA MapStruct二、项目结构src/main/java/com/example/codegen/ ├── Application.java ├── config/ │ ├── GeneratorConfig.java # 配置接口 │ └── GeneratorConfigImpl.java # 配置实现 ├── controller/ │ └── GeneratorController.java # REST API ├── manager/ │ └── TableMetaManager.java # 数据库元数据读取 ├── model/ │ ├── TableDTO.java # 表名注释 │ ├── TableMetaDTO.java # 完整表元数据 │ ├── ColumnMetaDTO.java # 列元数据 │ └── JavaType.java # Java类型名包名 ├── service/ │ └── GeneratorService.java # 核心生成ZIP打包 └── util/ └── StringUtils.java # snake_case/camelCase 转换 src/main/resources/ ├── application.yml └── templates/ # FreeMarker 模板目录 ├── BaseEntity.java.ftl # 基础框架 ├── BaseRepository.java.ftl ├── Query.java.ftl ├── QueryField.java.ftl ├── QueryType.java.ftl ├── Result.java.ftl ├── BusinessException.java.ftl ├── Entity.java.ftl # 业务代码 ├── Repository.java.ftl ├── Query.java.ftl业务Query与base不同路径 ├── Controller.java.ftl ├── ServiceImpl.java.ftl ├── Request.java.ftl └── Convertor.java.ftl注意base 框架模板和业务模板放在同一个templates/目录下base 模板以Base前缀命名区分。业务 Query 模板可以叫BizQuery.java.ftl或保留原名base 的 Query.java.ftl 和业务的区分开即可。三、REST APIGET /tables列出数据库中所有表返回ListTableDTOtableName tableCommentGET /table/gen参数参数必填说明author是作者名写入生成的类注释tablePrefix否表前缀生成类名时去掉如t_tableNames是表名逗号分隔basePackage是基础包名如com.examplemoduleName是模块名如order返回ZIP 文件下载内含 base 框架类 每表 7 个业务类按包路径组织。四、基础框架模板一些工具类或者公司/集团有对一些实体、查询等内部框架类继续沿用公司/集团风格创建对应的FreeMarker模版下列Base 模板7 个BaseEntity.java.ftl, BaseRepository.java.ftl, QueryType.java.ftl, QueryField.java.ftl, Query.java.ftl, Result.java.ftl, BusinessException.java.ftl业务模板7 个Entity.java.ftl, Repository.java.ftl, BizQuery.java.ftl, ServiceImpl.java.ftl, Controller.java.ftl, Request.java.ftl, Convertor.java.ftl命名避让base 的 Query.java.ftl 和业务的 BizQuery.java.ftl 使用不同文件名GeneratorService 核心逻辑create(author, tablePrefix, tableNames, basePackage, moduleName): 1. 获取 tableSchema从 DataSource.getConnection().getCatalog() 2. 解析 tableNames → ListString 3. 调用 TableMetaManager.getFullTableMeta() 获取表元数据 4. 创建 ByteArrayOutputStream ZipOutputStream 5. 渲染 base 模板数据模型Map.of(basePackage, basePackage) → 追加到 ZIP 6. 渲染业务模板数据模型TableMetaDTO逐表逐模板 → 追加到 ZIP 7. 返回 byte[]FreeMarker 配置classpath 模板路径/templates编码UTF-8异常处理IGNORE_HANDLER不因模板缺少属性而报错