当前位置: 首页 > news >正文

# 政务表单动态建表?运行时DDL引擎,前端拖完字段后端直接建

政务表单动态建表?运行时DDL引擎,前端拖完字段后端直接建

非科班野生程序员,深耕政务信息化20年。从VC到PB再到Java,自研框架browise也打磨了十几年。最近整理框架代码,发现不少有趣的决策,写出来和大家聊聊。最后感谢豆包、智谱、OpenCode,决策是我做的,代码是我搓的,文字是他们总结的。

场景

政务系统有个典型需求:业务人员在页面上设计表单,拖几个字段上去,点保存,后台就得在数据库里建一张物理表。不是虚拟表、不是JSON存储,是真正的物理表。因为后续要对接报表、对接工作流,没有物理表寸步难行。

而且还得支持 Oracle 和 SQL Server 两种数据库——信创改造期间两个库并行跑。

整体设计

前端拖字段 → JSON传到后端 → DDLop(入口) ↓ DDLinterface(接口) ↓ ↓ DDL_oracle_impl DDL_mssql_impl ↓ ↓ 拼Oracle DDL 拼MSSQL DDL ↓ 自动生成五级元数据(ea01~ea05)

第一层:DDLop — 入口控制器

// DDLop.java@aoppoint@bean(id="ddlop")@responseMapping(key="/ddlop")publicclassDDLop{@property(type="ref",value="ddlimpl_oracle")DDLinterfaceimpl;@Trans@monitoring@responseMapping(key="/createtable")@responseType(type=String.class)publicStringcreatetable(newDataStore<ddlDao>ddlds)throwsutilException{impl.createtable(ddlds);return"创建成功!";}@Trans@monitoring@responseMapping(key="/altertable")@responseType(type=String.class)publicStringaltertable(newDataStore<ddlDao>ddlds)throwsutilException{impl.alerttable(ddlds);return"修改成功!";}}

注意@property(type="ref", value="ddlimpl_oracle")——通过IoC容器注入具体实现。切数据库只改这一行配置,Oracle换成"ddlimpl_mssql"就行。

第二层:DDLinterface — 统一接口

// DDLinterface.javapublicinterfaceDDLinterface{publicvoidcreatetable(newDataStore<ddlDao>ddlds)throwsutilException;publicvoidalerttable(newDataStore<ddlDao>ddlds)throwsutilException;}

就两个方法:建表、改表。ddlDao里每个字段有columnnamedatatypedataleniskeydes这些属性。

第三层:DDL_oracle_impl — Oracle建表

建表过程分四步:

第一步:拼 CREATE TABLE

StringBufferbuffer=newStringBuffer();buffer.append("create table ");StringtableName=(String)ddlds.getParameter("tablename");buffer.append(tableName);buffer.append(" ( \r\n");for(inti=0;i<ddlds.getRowSet().getPrimary().size();i++){ddlDao dao=ddlds.getRowSet().getrow(i);buffer.append("\t");buffer.append(dao.getColumnname());buffer.append(" ");if("1".equals(dao.getDatatype()))buffer.append("varchar2(512)");if("2".equals(dao.getDatatype()))buffer.append("date");if("3".equals(dao.getDatatype()))buffer.append("number(18,2)");if("4".equals(dao.getDatatype()))buffer.append("date");if(dao.isIskey())buffer.append(" not null");if(i<ddlds.getRowSet().getPrimary().size()-1)buffer.append(",");buffer.append(" \r\n");}buffer.append(" ) \r\n");DBUtil.SaveDao(DDLMapper.class,"execsql",buffer.toString());

数据类型用编码:"1"是字符串,"2"是日期,"3"是数字,"4"是日期时间。前端传编码,后端按数据库方言翻译。

第二步:拼主键约束

buffer=newStringBuffer();buffer.append("alter table ");buffer.append(tableName);buffer.append(" add constraint ");buffer.append("PK_"+tableName+" ");buffer.append(" primary key ( ");// ... 遍历标记了iskey的字段buffer.append(" )");if(count>0)DBUtil.SaveDao(DDLMapper.class,"execsql",buffer.toString());

第三步:加表注释和字段注释

Stringtablesql="comment on table "+tableName+" is '"+tabledes+"'";DBUtil.SaveDao(DDLMapper.class,"execsql",tablesql);for(inti=0;i<ddlds.getRowSet().getPrimary().size();i++){ddlDao dao=ddlds.getRowSet().getrow(i);Stringsql="comment on column "+tableName+"."+dao.getColumnname()+" is '"+dao.getDes()+"'";DBUtil.SaveDao(DDLMapper.class,"execsql",sql);}

政务系统表注释是必须的,审计的时候说得清楚每个字段什么含义。

第四步:自动生成五级元数据

这是关键。如果表里有proc_inst_id_字段(说明这张表要挂工作流),就自动生成一套元数据:

if(isform){createsql(tableName,tabledes,ddlds);}

createsql方法会往ea01~ea05五张元数据表里写入记录:

  • ea01:表级定义(表名、表描述)
  • ea02:表别名映射
  • ea03:字段级定义(字段名、类型、排序、注释)
  • ea04:字段分组
  • ea05:默认查询条件(自动加proc_inst_id_作为关联条件)

有了这五级元数据,前端的列表页、查询条件、表单渲染都可以自动生成,不需要手写一行SQL。

第四层:DDL_mssql_impl — SQL Server建表

和 Oracle 实现几乎一样,区别只在数据类型映射和注释语法:

// Oracle: comment on table xxx is 'xxx'// MSSQL:Stringtablesql="execute sp_addextendedproperty 'MS_Description','"+tabledes+"','user','dbo','table','"+tableName+"',null,null ";// 字段注释Stringsql="EXECUTE sp_addextendedproperty 'MS_Description_c', '"+dao.getDes()+"', 'user', 'dbo', 'table', '"+tableName+"', 'column', '"+dao.getColumnname()+"'";

SQL Server 用sp_addextendedproperty加注释,修改注释的时候先add,失败了再update

try{DBUtil.SaveDao(DDLMapper.class,"execsql",sql);}catch(utilException e){sql="EXECUTE sp_updateextendedproperty 'MS_Description_c', '"+dao.getDes()+"', 'user', 'dbo', 'table', '"+tableName+"', 'column', '"+dao.getColumnname()+"'";DBUtil.SaveDao(DDLMapper.class,"execsql",sql);}

这种"先试增再改"的方式很务实,比先查后判断省一轮数据库交互。

改表支持什么

alerttable方法支持三种操作:

  1. 加字段:遍历primary列表,isInsert()为 true 的拼ALTER TABLE ADD
  2. 删字段:遍历delete列表,isModefiy()为 true 的拼ALTER TABLE DROP COLUMN
  3. 改注释:重新写入所有字段注释

注意字段状态复用了 BaseDao 的_t状态机,新增=1,修改=3,删除=4。

小结

整个 DDL 引擎就三个类加一个接口,加起来不到700行代码,但解决了政务系统里"表单设计器拖字段后端自动建表"的完整链路。Oracle 和 SQL Server 切换只改一行IoC配置。五级元数据自动生成,前端列表查询表单全自动渲染。


做过动态建表的同学来聊聊,你们是怎么处理的?评论区见。

标签:#Java #DDL #动态建表 #Oracle #SQLServer #政务信息化 #自研框架

http://www.jsqmd.com/news/617933/

相关文章:

  • 跨平台直播录制利器Fideo:从技术架构到实战应用的深度解析
  • Deep Sort PyTorch:多目标跟踪的完整实践指南
  • 反爬虫对抗策略在海淘场景的应用
  • 使用GitHub Actions实现Janus-Pro-7B模型服务的CI/CD自动化流水线
  • NineData 2026年3月功能上新:支持飞书外部审批,增强慢查询分析与数据复制能力
  • 011、AI赋能传统行业:制造、医疗、金融的改造案例
  • Gitee领跑2025代码托管市场,全链路DevOps能力重塑开发体验
  • 2026青海纯玩小团优选!舒途凯旋旅行社青海分社一站式服务 - 深度智识库
  • R 4.5微生物组批量QC失败率高达67%?:5步标准化预处理流水线(含fastp+dada2+decontam一键脚本)
  • Bagging与Boosting的实战对比:如何选择适合的集成学习方法
  • 云南CAAC无人机培训哪家靠谱?权威机构实力盘点 - 深度智识库
  • 终极实战:ALOHA低成本开源双手机器人遥操作系统深度指南
  • Qwen3-0.6B快速上手:5分钟在Jupyter中调用LangChain对话机器人
  • FlicFlac音频格式转换:5分钟学会Windows免费音频转换工具
  • Intv_ai_mk11 企业级部署架构设计:高可用与弹性伸缩实战
  • 断舍离新思路:闲置大润发购物卡,这样变现更有价值 - 团团收购物卡回收
  • 进口+国产机床采购指南:这三个专业网站值得收藏 - 品牌推荐大师
  • 保姆级教程:在ROS2 Humble上搞定串口通信,从源码编译到避坑全记录
  • Ubuntu远程桌面总掉线?我给你指两条活路
  • 别再被ChatGPT的‘一本正经胡说八道’骗了!手把手教你用‘语义熵’给AI答案做个‘可信度体检’
  • 从无人机到自动驾驶:自适应卡尔曼滤波如何解决传感器‘打架’问题?
  • 像素皇城灵蛇贺岁实测:输入愿望秒出春联,8-bit复古风太惊艳了
  • 2026年贵阳装修公司选购指南:3招教你省钱挑对高性价比服务 - 精选优质企业推荐榜
  • 2026年西安装修公司综合选购推荐报告:陕西鲁班装饰工程有限公司 - 2026年企业推荐榜
  • KKS-HF_Patch完全指南:3步解锁Koikatsu Sunshine完整游戏体验
  • 博途S7-1200与昆仑通态MCGS纯仿真联调实战指南
  • 连华强北都扛不住,有黄牛囤一屋内存条亏麻了
  • 5分钟解决网盘下载难题:八大平台直链解析工具LinkSwift
  • 5大核心技巧揭秘:如何深度挖掘AMD Ryzen处理器的隐藏性能潜力
  • 中电金信汽车智能座舱解决方案,让驾驶“更懂你”