# codgen **Repository Path**: htengen/codgen ## Basic Information - **Project Name**: codgen - **Description**: Codgen是一个基于数据库元数据模型,使用freemarker模板引擎来构建输出的代码生成器。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 178 - **Forks**: 62 - **Created**: 2015-07-20 - **Last Updated**: 2026-04-02 ## Categories & Tags **Categories**: code-generator **Tags**: None ## README # Codgen - 基于数据库元数据的代码生成器 [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) [![Java](https://img.shields.io/badge/Java-1.7+-green.svg)]() [![FreeMarker](https://img.shields.io/badge/FreeMarker-2.3.20-orange.svg)]() ## 📖 简介 **Codgen** 是一个强大而灵活的代码生成器,它基于数据库元数据模型,使用 FreeMarker 模板引擎自动生成多层架构的代码文件。通过简单的配置和模板定义,您可以快速生成符合项目规范的 DAO、BLL、Model 等各层代码,大幅提高开发效率。 ### 💡 核心理念 ``` 数据模型 (TableModel) + 模板 (Template) = 输出 (Output) ``` Codgen 通过 JDBC 获取数据库表的元数据信息,封装成丰富的数据模型,再结合 FreeMarker 模板引擎,生成符合您需求的代码文件。 ## ✨ 核心特性 - 🔍 **基于 JDBC 的元数据获取**:自动获取表结构、列信息、主键、外键、索引等完整的数据库元数据 - 🎯 **灵活的数据类型转换**:通过 `ColumnHandler` 接口实现 JDBC 类型到各种编程语言类型的转换 - 🏗️ **强大的模板引擎**:基于 FreeMarker,支持文件模板和文本模板,可嵌套引用数据模型 - 🔌 **可扩展的架构设计**:支持自定义 `DbProvider` 适配不同数据库,支持自定义 `BuildConfigHandler` 进行定制处理 - 📦 **配置驱动**:XML 配置文件支持多项目、继承机制、动态数据模型定义 - 🚀 **高效构建**:一次性加载配置并缓存,支持多种输出类型(文件/文本) - 🌐 **跨数据库支持**:内置 Oracle、SQL Server、MySQL 等多种数据库支持 ## 🚀 快速开始 ### 环境要求 - **JDK**: 1.7 或以上版本 - **依赖库**: - `commons-lang.jar` (2.6 或以上) - `commons-logging.jar` (1.2 或以上) - `log4j-1.2.14` 或以上 - `freemarker-2.3.13` 或以上 - 数据库 JDBC 驱动(如:`ojdbc14.jar`、`sqljdbc.jar` 等) ### 配置文件示例 创建 `codgen-config.xml` 配置文件: ```xml com.microsoft.sqlserver.jdbc.SQLServerDriver jdbc:sqlserver://127.0.0.1\SQL2005;DatabaseName=MUCM_DG;selectMethod=cursor sa sa | template/AOWork D:/QtoneProject/TengenCode/${copyright.author}/${projectName} com.qtone.aow.model.${groupName} com.qtone.aow.dao.${groupName} com.qtone.aow.bll.${groupName} ${outputDirectory}/Bll.java ``` ### 代码调用示例 #### Web 环境使用(JSP/Servlet) ```java // 获取项目配置信息 ProjectConfig projectConfig = ProjectConfigHelper.getProjectConfig( servletContext.getInitParameter("codgen.config"), projectName ); // 创建构建配置 ProjectBuildConfig buildConfig = new ProjectBuildConfig(projectConfig); buildConfig.setTableName(tableName); // 设置表名:Sys_UserInfo buildConfig.setTableLabel(tableLabel); // 设置表标签:用户信息 buildConfig.setGroupName(groupName); // 设置组名:System buildConfig.setModuleName(moduleName); // 设置模块名:UserInfo buildConfig.getCopyright().setAuthor(author); // 初始化配置并执行构建 buildConfig.initConfig(); Builder builder = new CodeBuilder(buildConfig); Map omMap = builder.build(); // 获取生成结果 for (Entry entry : omMap.entrySet()) { System.out.println("生成内容 = " + entry.getValue().getOutput()); } ``` #### 非 Web 环境使用(Java SE) ```java public static void main(String[] args) { // 加载配置文件 ProjectConfig projectConfig = ProjectConfigHelper.getDefaultProjectConfig("codgen-config.xml"); // 创建构建配置 ProjectBuildConfig buildConfig = new ProjectBuildConfig(projectConfig); buildConfig.setTableName("Sys_UserInfo"); // buildConfig.setTableLabel("用户信息"); // 不设置则默认为表注释 // buildConfig.setGroupName("System"); // 不设置则默认为 Sys // buildConfig.getCopyright().setAuthor("黄天政"); // 不设置则默认为当前计算机用户名 // 执行代码生成 Builder builder = new CodeBuilder(buildConfig); Map omMap = builder.build(); // 输出生成结果 for (Entry entry : omMap.entrySet()) { System.out.println("生成内容 = " + entry.getValue().getOutput()); } } ``` ## 📚 配置详解 ### 核心配置节点 #### 1. project 节点 - 项目定义 一个项目是最小构建单位。 | 属性 | 必填 | 说明 | |------|------|------| | **name** | ✅ | 项目名称,在所有配置中必须唯一 | | **label** | ✅ | 项目标签,中文描述信息,用于前端显示 | | **outputEncoding** | ✅ | 输出编码类型(如:UTF-8、GBK),必须与模板编码一致 | | **isDefault** | ❌ | 是否默认项目,多个默认项目时以最后一个为准 | | **extends** | ❌ | 继承已有的项目配置,实现配置复用 | | **isEnabled** | ❌ | 是否启用,默认 `true`,禁用的项目不会被加载 | #### 2. dbProvider 节点 - 数据库信息提供者 配置数据库方言和元数据获取方式。 ```xml com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mydb root password mydb | ``` **支持的数据库**: - ✅ Oracle 10g+ - ✅ SQL Server 2000/2005+ - ✅ MySQL 5.x/8.x - 🔧 可通过扩展 `DbProvider` 支持更多数据库 #### 3. dataModel 节点 - 数据模型定义 数据模型是模板中可动态替换的变量。 ```xml MyCodeGenerator Hello, ${codgen}! D:/Projects/${copyright.author}/${projectName} ``` **内置数据模型**: - `projectName` - 项目名称 - `projectLabel` - 项目标签 - `tableName` - 表名称(必须指定) - `tableLabel` - 表标签(默认取表注释) - `groupName` - 分组名称(如:Sys) - `moduleName` - 模块名称(如:UserInfo) - `copyright` - 版权信息对象 - `templateDirectory` - 默认模板目录 - `table` - **核心数据模型** TableModel 对象 #### 4. template 节点 - 模板定义 ```xml ``` #### 5. output 节点 - 输出配置 ```xml ${outputDirectory}/Dao/${tableName}Dao.java old_output.txt ``` **优先级规则**:`templateContent` > `templateFile` > `templateName` ### 高级扩展 #### 自定义 ColumnHandler 处理列名的命名转换、数据类型转换等。 ```java /** * Oracle 下划线转驼峰命名处理器 */ public class OracleColumnHandler implements ColumnHandler { @Override public void handle(ColumnModel col) { String columnName = col.getColumnName().toLowerCase(); StringBuilder sb = new StringBuilder(); boolean capitalizeNext = false; for (char c : columnName.toCharArray()) { if (c == '_') { capitalizeNext = true; } else { sb.append(capitalizeNext ? Character.toUpperCase(c) : c); capitalizeNext = false; } } col.setColumnName(sb.toString()); } } ``` #### 自定义 BuildConfigHandler 在构建生命周期的各个阶段进行定制处理。 ```java public class CustomBuildConfigHandler implements BuildConfigHandler { @Override public void initConfig(BuildConfig config) { // 配置初始化时的处理逻辑 ProjectBuildConfig pbConfig = (ProjectBuildConfig) config; String tableName = pbConfig.getTableName(); // 自动从表名提取组名和模块名 if (tableName.contains("_")) { pbConfig.setGroupName(StringUtils.substringBefore(tableName, "_")); pbConfig.setModuleName(toCamelCase(tableName)); } } @Override public void beforeGetDataModel(BuildConfig config) { // 获取数据模型之前的处理 } @Override public void afterGetDataModel(BuildConfig config) { // 获取数据模型之后的处理 } @Override public void beforeGetOutputModel(BuildConfig config) { // 获取输出模型之前的处理 } @Override public void afterGetOutputModel(BuildConfig config) { // 获取输出模型之后的处理 } private String toCamelCase(String str) { return StringUtils.capitalize(str.replace("_", "")); } } ``` ## 🔧 最佳实践 ### 1. 配置文件组织 对于复杂项目,建议将配置分散到多个文件: ``` config/ ├── codgen-config.xml # 主配置文件 ├── codgen-module-a.xml # 模块 A 配置 └── codgen-module-b.xml # 模块 B 配置 ``` 在 `web.xml` 中配置: ```xml codgen.config codgen-config.xml,codgen-module-a.xml,codgen-module-b.xml ``` ### 2. 表注释和列注释规范 为了提高生成代码的可读性,建议遵循以下注释规范: ```sql -- 表注释格式:表标签 | 表详细描述 COMMENT ON TABLE sys_user_info IS '用户信息 | 存储教师、家长、学生等各类用户的基本资料'; -- 列注释格式:列标签 | 列详细说明 COMMENT ON COLUMN sys_user_info.user_code IS '用户编码 | 由程序生成 UUID,去掉下划线后的 32 位编码'; COMMENT ON COLUMN sys_user_info.user_name IS '用户姓名 | 用户的真实姓名,中文或英文'; ``` 配合配置文件中的分隔符设置: ```xml | ``` ### 3. 模板文件组织 ``` template/ └── MyProject/ ├── include/ │ ├── copyright.ftl # 版权信息模板 │ └── header.ftl # 文件头模板 ├── Model.ftl # 实体类模板 ├── Dao.ftl # DAO 接口模板 ├── DaoImpl.ftl # DAO 实现模板 ├── Bll.ftl # BLL 接口模板 └── BllImpl.ftl # BLL 实现模板 ``` ## 📊 架构图 ``` ┌─────────────────────────────────────────────────────────┐ │ Codgen 架构 │ ├─────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ 配置文件 │ │ 模板文件 │ │ │ │ XML Config │ │ FreeMarker │ │ │ └──────┬───────┘ └──────┬───────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ ProjectConfigHelper │ │ │ │ - 加载配置 │ │ │ │ - 解析数据模型 │ │ │ │ - 注册处理器 │ │ │ └──────────────┬──────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ ProjectBuildConfig │ │ │ │ - 表名/组名/模块名 │ │ │ │ - 版权信息 │ │ │ │ - BuildConfigHandler 回调 │ │ │ └──────────────┬──────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ DbProvider (JDBC) │ │ │ │ - 获取表元数据 │ │ │ │ - 获取列信息 │ │ │ │ - 主键/外键/索引 │ │ │ │ - ColumnHandler 处理 │ │ │ └──────────────┬──────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ TableModel (数据模型) │ │ │ │ - 表信息 │ │ │ │ - ColumnModel[] │ │ │ │ - PrimaryKey[] │ │ │ │ - ForeignKey[] │ │ │ └──────────────┬──────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ CodeBuilder + FreeMarker │ │ │ │ - 数据模型 + 模板 → 输出 │ │ │ └──────────────┬──────────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ OutputModel[] │ │ │ │ - Model.java │ │ │ │ - Dao.java / DaoImpl.java │ │ │ │ - Bll.java / BllImpl.java │ │ │ └─────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────┘ ``` ## 🎯 典型使用场景 1. **企业级应用开发**:快速生成标准的三层架构代码(DAO/BLL/Model) 2. **微服务开发**:为每个微服务生成独立的持久层代码 3. **遗留系统改造**:从现有数据库反向生成代码,再进行定制修改 4. **多数据库适配**:通过 ColumnHandler 实现不同数据库的命名规范转换 5. **批量代码生成**:一次性为几十上百张表生成基础代码 ## 📝 常见问题 ### Q1: 如何处理 MySQL 8 查询所有数据库的问题? **A**: 在配置文件中显式指定 `catalog` 节点: ```xml com.mysql.cj.jdbc.Driver jdbc:mysql://localhost:3306/mydb?useSSL=false root password mydb ``` ### Q2: 如何实现 Oracle 下划线列名转驼峰命名? **A**: 实现自定义 ColumnHandler 并在配置文件中注册: ```xml ``` ### Q3: 如何禁用某个输出模型? **A**: 在 output 节点设置 `disabled="true"`: ```xml old_file.txt ``` ### Q4: 配置文件放在哪里? **A**: - **Web 环境**:建议在 `WEB-INF/classes` 或自定义目录,通过 `web.xml` 配置 - **Java SE**:放在 `src` 目录下,编译后会在 classpath 根目录 ## 📄 更新日志 详细版本更新记录请参考 [CHANGELOG.md](CHANGELOG.md) ## 🤝 贡献 欢迎提交 Issue 和 Pull Request 来帮助改进 Codgen! ## 📧 联系方式 - **作者**: 黄天政 - **项目主页**: [Gitee](https://gitee.com/codgen) ## 📖 许可证 Codgen 使用 Apache 2.0 许可证。详情参见 [LICENSE](LICENSE) 文件。 --- **Happy Coding! 🚀**