# 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)
[]()
[]()
## 📖 简介
**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}
dao.ftl
```
### 代码调用示例
#### 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
template/Model.ftl
```
#### 5. output 节点 - 输出配置
```xml
```
**优先级规则**:`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
```
### 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! 🚀**