应用案例 · 源码级分析

智能代码生成平台

pig4cloud 多数据源元数据引擎深度解析

基于 pig4cloud codegen 源码分析,揭示 AnyLine 如何驱动"多数据源接入 → 表结构逆向 → 动态建表 → 代码自动生成"全链路, 一行代码不写,连接任意数据库。

ServiceProxy.service() metadata().tables() ddl().create() DataSourceHolder 7 种数据库方言
7
数据库方言支持
4
核心元数据 API
1 步
数据源切换
0 行
手写 SQL / Mapper
1

整体架构:AnyLine 驱动全链路代码生成

多数据源 → 元数据解析 → 动态建表 → 代码生成,四步闭环

配置数据源 MySQL / PG / Oracle / DM 达梦 / HighGo / DB2 / MSSQL AnyLine metadata().tables() ServiceProxy.service() 解析元数据 Table / Column / Database DDL 语句逆向生成 动态建表 ddl().create(table) 自动建表或导入已有表 代码生成 Entity / Mapper / Service Controller / VO / DTO
源文件 AnyLine 使用方式 核心价值
DsTypeEnum 定义 7 种数据库的 AnyLine Adapter 全类名 运行时检测方言插件是否已加载
AnylineDataSourceHelper DataSourceHolder.reg() 按需注册数据源到 AnyLine 统一封装数据源上下文切换,finally 中自动清理
CreateTableHandler service.ddl().create(table) / service.ddl().drop(table) 可视化配置 → 自动执行 CREATE TABLE,全程零 SQL
GenTableServiceImpl metadata().tables() / metadata().columns() / queryTableDdl() 逆向解析任意数据源表结构,生成 DDL 和字段信息
GenDatasourceConfServiceImpl ClassUtil.loadClass(adapterClassName) 检测方言 判断 pom.xml 中是否引入某数据库的 AnyLine 适配器
2

核心能力一:7 大数据库方言零缝适配

DsTypeEnum:数据库类型 + JDBC URL 模板 + AnyLine Adapter 全类名,一行定义

🐬
MySQL
MySQLAdapter
🐘
PostgreSQL
PostgresqlAdapter
📋
SQL Server
MSSQLAdapter
🔶
Oracle
OracleAdapter
🟦
DB2
DB2Adapter
国产
🟩
达梦 DM
DMAdapter
国产
🦅
HighGo 人大金仓
HighgoAdapter
⚙️
新增数据库
只需在枚举加一行
// DsTypeEnum.java — 一行定义一种数据库的完整配置
public enum
DsTypeEnum {
// MySQL
MYSQL("mysql", "jdbc:mysql://%s:%s/%s...", "select 1",
"mysql8 链接", "org.anyline.data.jdbc.mysql.MySQLAdapter"),
// 达梦(国产)
DM("dm", "jdbc:dm://%s:%s/%s", "select 1 from dual",
"达梦连接", "org.anyline.data.jdbc.dm.DMAdapter");
// 切换数据库:只需修改 pom.xml 依赖,业务代码零改动
// GenDatasourceConfServiceImpl.listParserPlugins() — 检测方言适配器是否已加载
Map<String, Boolean> result = new LinkedHashMap<>();
for (DsTypeEnum dsEnum : DsTypeEnum.values()) {
result.put(dsEnum.getDbName(),
isClassPresent(dsEnum.getAnylineAdapter()));
}
// 返回 {"mysql": true, "dm": false, "oracle": true, ...} — 告诉用户缺少哪个适配器
3

核心能力二:AnylineDataSourceHelper 数据源上下文封装

三件事,一次封装,全部搞定

业务层只需要关注具体操作逻辑,不再重复处理数据源切换细节

🔍
获取动态数据源
从 DynamicRoutingDataSource 中按名称取出
📋
向 AnyLine 注册
DataSourceHolder.reg() 按需注册,避免重复
🧹
切换 & 清理上下文
DynamicDataSourceContextHolder.push() → finally clear()
无返回值 AnylineDataSourceHelper.run(dsName, action)
// 最常用写法:切换数据源 + 执行 + 自动清理
AnylineDataSourceHelper.run(dsName, () -> {
createTableService.createTable(vo);
// AnyLine 在后台自动切换到 dsName 对应的数据源
});
有返回值 AnylineDataSourceHelper.execute(dsName, supplier)
// 带返回值:元数据查询、表同步等场景
GenTable table =
AnylineDataSourceHelper.execute(dsName, () -> {
Table meta =
ServiceProxy.service().metadata().table(name);
return buildGenTable(meta);
});
核心逻辑 registerIfAbsent — 按需注册,防止重复
// 关键:已注册则跳过,未注册才注册
private void registerIfAbsent(String dsName, DataSource ds) {
if (DataSourceHolder.exists(dsName)) {
return;
}
DataSourceHolder.reg(dsName, ds);
}
4

核心能力三:跨数据源元数据解析

GenTableServiceImpl — 三类元数据 API,零 SQL 实现表结构逆向

API 1 queryTableDdl — 逆向生成建表 DDL
// 输入表名 → 输出 DDL 语句,全程 AnyLine 自动生成 SQL
public String queryTableDdl(String dsName, String tableName) {
DynamicDataSourceContextHolder.push(dsName);
Table table = ServiceProxy.metadata().table(tableName);
table.execute(false); // 不执行,只生成 SQL
ServiceProxy.ddl().create(table);
return table.getDdl(); // MySQL 返回 CREATE TABLE ...
}
API 2 queryTableColumn — 解析表的所有字段元数据
// 一次性获取表的所有列:字段名、类型、注释、主键、自增
public List<Column> queryTableColumn(String dsName, String tableName) {
DynamicDataSourceContextHolder.push(dsName);
CacheProxy.clear(); // 清除缓存,保证最新
return ServiceProxy.metadata().columns(tableName).values()
.stream().toList();
}
API 3 queryTablePage — 分页浏览数据源下的所有表
// 按表名/注释模糊搜索,按创建时间倒序,支持分页
public IPage<Table> queryTablePage(Page page, GenTable table) {
DynamicDataSourceContextHolder.push(table.getDsName());
CacheProxy.clear();
List<Table> list = ServiceProxy.metadata().tables()
.values().stream()
.filter(t -> StrUtil.containsIgnoreCase(...))
.sorted(...).toList();
return CollUtil.page(..., list);
}
5

核心能力四:可视化配置驱动动态建表

CreateTableHandler — UI 配置字段 → AnyLine DDL 执行,全程零手写 SQL

前端可视化 配置表名+字段 列名/类型/注释 CreateTableHandler createTable(dsName, info) new Table() + addColumn() AnyLine DDL metadata().table() ddl().drop() / create() MySQL / PG / DM CREATE TABLE ... ✓ 执行成功
// CreateTableHandler.createTable — 核心逻辑
public Boolean createTable(String dsName, TableInfo tableInfo) {
AnylineService service = ServiceProxy.service(dsName);
// 检查表是否已存在,已存在则删除后重建
Table table = service.metadata().table(tableInfo.getName(), false);
if (null != table) service.ddl().drop(table);
// 执 行建表:AnyLine 根据数据源类型自动生成方言 SQL
service.ddl().create(tableInfo);
return true;
}
// CreateTableServiceImpl — 前端 VO → AnyLine Column 模型
private Column buildColumn(GenCreateTableColumnVO col) {
Column column = new Column();
column.setName(col.getName());
column.setType(col.getType());
column.setComment(col.getComment());
column.setLength(col.getLength());
column.setPrimary(col.getPrimary());
column.setAutoIncrement(col.getAutoIncrement());
return column;
}
// GenCreateTableController.save() — 控制器调用封装
@PostMapping
public R save(@RequestBody GenCreateTableVO vo) {
AnylineDataSourceHelper.run(vo.getDsName(),
() -> createTableService.createTable(vo));
return R.ok(createTableService.saveOrUpdate(genTable));
}
6

MyBatis × AnyLine:动静互补的代码生成架构

MyBatis 平台系统表 CRUD
GenTable — 代码生成的表配置
GenTableColumn — 字段配置
GenDatasourceConf — 数据源连接配置
GenCreateTable — 动态建表记录
编译时结构已知,ServiceImpl 标准 CRUD
AnyLine 多数据源元数据 + DDL
ServiceProxy.metadata() — 跨数据源查表/列
ddl().create() / ddl().drop() — 动态建表/删表
DataSourceHolder — 动态数据源注册
AnylineDataSourceHelper — 上下文封装
运行时结构未知,AnyLine 统一处理
用户操作 配置/建表/查询 codegen 平台 MyBatis:系统表 CRUD AnyLine:元数据 + DDL MyBatis GenTable / Column AnyLine metadata() / ddl() 目标数据库 MySQL / PG / Oracle / 达梦 / HighGo DB2 / MSSQL
7

案例总结

AnyLine 在 pig4cloud codegen 中的定位

多数据源代码生成的数据库抽象层

🌐
多数据源元数据
metadata() 统一抽象
🗄️
DDL 方言适配
create/drop 自动方言转换
🔌
动态数据源注册
DataSourceHolder 热插拔
🔍
方言插件检测
isClassPresent 运行时判断

💡 AnyLine 价值

验证"元数据驱动"核心定位:pig4cloud codegen 将 AnyLine 的元数据能力发挥到极致——连接任意数据库,自动解析表结构、字段、主键、自增、注释,生成完整 CRUD 代码,全程零 SQL。

国产数据库适配的标杆场景:达梦 DM 和 HighGo 人大金仓通过 AnyLine 统一接入,无需为每种数据库写定制代码,一套逻辑覆盖全部。

🎯 可复制的技术路径

代码生成器的标准数据层范式:AnyLine metadata() + MyBatis 双引擎是所有代码生成器的最优数据层架构,MyBatis 管配置,AnyLine 管目标数据库。

数据源管理层封装模板:AnylineDataSourceHelper 是多数据源环境下 AnyLine 集成的最佳实践封装,registerIfAbsent + push + finally clear 三步标准化。

源码分析来源
• DsTypeEnum.java — 7 种数据库类型定义,含 AnyLine Adapter 全类名
• GenTableServiceImpl.java — metadata() 元数据解析(tables / columns / DDL 逆向)
• GenDatasourceConfServiceImpl.java — 动态数据源 CRUD + 方言插件检测
• GenCreateTableController.java — 可视化建表接口(AnylineDataSourceHelper.run)
• GenDsConfController.java — 数据源管理接口 + 文档生成
• CreateTableServiceImpl.java — 前端 VO → AnyLine Column 模型构建
• CreateTableHandler.java — ddl().create() / ddl().drop() 动态建表核心逻辑
• AnylineDataSourceHelper.java — 数据源上下文统一封装

分享案例获取系统性的技术支持

每一次数据库成功切换的背后,都有一段充满技术挑战与架构演进的故事