大数跨境

SpringBoot3 + openGauss:RuoYi Office 登录、流程发布与用印填报适配实战

SpringBoot3 + openGauss:RuoYi Office 登录、流程发布与用印填报适配实战 企业软件源码
2026-10-30
1
导读:基于 RuoYi Office openGauss 运行验证,讲清官方 JDBC、日志依赖隔离、Flowable 类型识别、流程仓库与序列校准如何支撑登录、流程发布和用印填报,并明确完整审批的后续验收

SpringBoot3 + openGauss:RuoYi Office 登录、流程发布与用印填报适配实战

openGauss 迁移中,最有价值的结果不是“驱动能连接”,而是员工能进入工作台、流程模型能发布、业务表单能打开。本文围绕 RuoYi Office 的实测路径,解释官方 JDBC、Flowable 数据库识别、流程资源和序列校准如何共同支撑产品运行。

▲ 蓝图分别标注数据库、连接、引擎和产品页面。本轮 openGauss 证据覆盖登录、流程发布与用印填报,没有把完整审批作为最终通过项。

引言:兼容 PostgreSQL,为什么还要单独适配?

数据库之间的兼容通常有层次:通信协议、SQL 语法、数据类型、系统视图、认证机制和工具行为,
 不必然同时等价。

openGauss 能提供 PostgreSQL 风格的应用接入,不意味着某个 PostgreSQL 驱动能够处理指定版本
 的全部认证流程,也不意味着工作流引擎能从产品名自动选对 SQL。

RuoYi Office 的实验环境就遇到过这种组合问题:数据库已经运行,应用仍在驱动或日志依赖阶段
 失败;处理后能登录,发布流程时又遇到资源或序列问题。

兼容层
需要实际核对的内容
产品影响
JDBC 认证
指定驱动与数据库认证模式
应用能否建立连接
Java 依赖
驱动内嵌类与应用日志体系
服务能否完成启动
引擎识别
JDBC 产品名与 Flowable 类型
流程 SQL 是否可运行
初始化数据
模型、部署、定义和资源
能否发布和发起流程
主键序列
新 ID 与历史最大值
新增和发布是否冲突

本篇把这些技术点放在“登录 → 发布 → 填报”的产品主线上,说明各项适配究竟解决哪一步。

一、先看登录与业务入口

实验环境采用 openEuler、毕昇 JDK、Tengine 与 openGauss 5.0.0。数据库和 schema 使用
ruoyi_office,数据库编码为 UTF-8,采用 PG 兼容模式。

1. 登录后的工作台验证基础读写链路

▲ 既有开发环境真实工作台,说明用户入口;openGauss 登录通过的结论来自历史实验记录,不能从此图推断数据库类型。

登录会涉及用户、角色、菜单与会话。工作台展示正常,说明认证与部分数据查询链路可用,但仍未
 覆盖模型发布中的新增 ID 和流程资源处理。

对迁移人员而言,下一步不是继续拍首页,而是打开一个存在发布资源的模型,并检查业务表单能否
 从流程入口进入。

2. 流程设计器和发起入口不能混为一谈

▲ 既有开发环境通用表单模型的配置页,可以看到发布按钮与权限设置;用于说明模型配置和运行定义的区别,没有在本次操作中发布模型。

设计器保存的是模型内容,发布后才能形成运行时使用的部署与流程定义。模型存在、模型可打开、
 存在激活定义,是三个不同检查点。

▲ 本地环境真实发起入口,用于观察可发起流程。国产库迁移时,应核对目标 key 和激活定义,而非仅要求入口页面不报错。

3. 用印填报覆盖业务字段与关联资料

▲ 既有开发环境用印表单,说明印章、人员、时间与文件字段;openGauss 历史验证范围是可填报至最终提交前。

用印表单同时访问业务资料与组织数据。中文、时间和选择项是否正常,能帮助判断初始化数据与字
 段契约是否保持了业务语义。

到达填报页面仍不能推导审批成功。对于客户验收,应在获准测试环境继续验证提交、任务流转和结
 果回写。

二、先解决 JDBC 接入,再讨论业务 SQL

1. 用官方驱动配对目标认证方式

实验中 PostgreSQL JDBC 曾在当前 openGauss SCRAM 认证路径报错。最终采用 openGauss 官方驱
 动与 jdbc:opengauss: URL,认证与连接建立通过。

这个结果的含义是:当前版本组合需要指定驱动。它并不是“所有 PostgreSQL 驱动都永远不能连接
 openGauss”的泛化结论。

当前 Profile 把驱动类和 URL 明确写在目标环境中。

    datasource:      master:        driver-class-name: org.opengauss.Driver        url: {DB_USERNAME:ruoyi_office}        password: {DB_URL:jdbc:opengauss://127.0.0.1:5432/ruoyi_office?currentSchema=ruoyi_office&batchMode=off}        username: {DB_PASSWORD:please-change-me}data:  redis:    host: {REDIS_PORT:6379}    database: {REDIS_PASSWORD:please-change-me}

currentSchema 控制对象查找上下文,账号控制可访问权限,Profile 决定应用选择的运行时配置
 。它们缺一不可,不能只关注 URL 中的主机与端口。

实验 URL 还显式设置了 batchMode=off。现场应沿用已验证组合,若希望调整批处理行为,再以
 实际批量写入与事务结果验证。

2. 处理驱动中的内嵌日志依赖

当前官方 JDBC 包带有旧版 SLF4J 类。Spring Boot 3 使用自己的日志依赖栈,直接把整包混入应
 用,可能产生版本冲突。

工程处理采用白名单解包:只嵌入 org/opengauss/** 与 JDBC 服务提供者文件,同时在 Boot 打
 包中排除原驱动整包。

<execution>    <id>embed-opengauss-driver-without-slf4j</id>    <phase>process-classes</phase>    <goals>        <goal>unpack</goal>    </goals>    <configuration>        <artifactItems>            <artifactItem>                <groupId>org.opengauss</groupId>                <artifactId>opengauss-jdbc</artifactId>                <version>{project.build.outputDirectory}</outputDirectory>                <includes>org/opengauss/**,META-INF/services/java.sql.Driver</includes>            </artifactItem>        </artifactItems>    </configuration></execution>

服务提供者文件让 Java 能发现 JDBC 驱动,驱动命名空间提供连接实现;旧日志类不应因驱动一起
 进入运行时类路径。

这是针对当前依赖包内容的工程处理,不应抽象成“所有 JDBC 驱动都需要解包”。升级驱动时要重新
 检查包内容,避免沿用已经不适合的打包规则。

处理方式
解决的问题
需要保持的内容
白名单嵌入
避免旧日志类冲突
官方驱动实现
保留 SPI 文件
让 JDBC 驱动可发现
java.sql.Driver
 描述
排除原整包
防止旧类再次打包
应用自己的日志依赖
升级后重检
发现包结构变化
认证、启动与日志完整性

三、Flowable 如何识别 openGauss

1. JDBC 产品名不是 PostgreSQL

Flowable 读取连接元数据确定数据库类型。openGauss 的产品名并不等于 PostgreSQL,因此引擎不
 能仅靠默认识别获得所需方言。

当前配置读取产品名,将 openGauss / GaussDB 映射为 Flowable 的 postgres 路径,再继
 续注册监听器与业务行为工厂。

return configuration -> {    // openGauss is PostgreSQL-compatible, but Flowable cannot infer that from its JDBC product name.    try (var connection = configuration.getDataSource().getConnection()) {        String productName = connection.getMetaData().getDatabaseProductName();        if ("openGauss".equalsIgnoreCase(productName) || "GaussDB".equalsIgnoreCase(productName)) {            configuration.setDatabaseType("postgres");        } else if ("DM DBMS".equalsIgnoreCase(productName) || "DM".equalsIgnoreCase(productName)) {            // DM8 is Oracle-compatible for Flowable's SQL dictionary and paging.            configuration.setDatabaseType("oracle");        }    } catch (SQLException ex) {        throw new IllegalStateException("Failed to determine the Flowable database type", ex);    }    // 注册监听器,例如说 BpmActivityEventListener    configuration.setEventListeners(ListUtil.toList(listeners.iterator()));    // 设置 ActivityBehaviorFactory 实现类,用于流程任务的审核人的自定义    configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory);    // 设置自定义的函数    configuration.setCustomFlowableFunctionDelegates(ListUtil.toList(customFlowableFunctionDelegates.stream().iterator()));};

映射解决的是引擎 SQL 路径选择。它不替代 schema 初始化、不修复丢失的部署数据,也不保证某
 个未验证数据库版本的全部行为等价。

2. 建表与引擎启动使用不同责任边界

当前信创 Profile 关闭 Flowable 自动建表。初始化表与数据应由目标库 SQL 交付,应用启动只检
 查并使用这些资源。

如果启动缺表,不应为了“尽快启动”直接打开自动建表并改变目标库结构。先确认目标包、schema
 和版本是否匹配。

Quartz 同样采用 JDBC 持久化,openGauss 选择 PostgreSQL Delegate。主键策略与 Quartz 策略
 是独立判断,不能由“都是 PG 兼容库”一句话带过。

四、模型能打开,为什么发布资源仍可能丢失

1. 资源关系比模型数量更重要

▲ 模型面向设计,部署与流程定义面向运行,字节资源保存模型或部署内容;图示为业务逻辑关联,不代表所有关系都有物理外键。

数据对象
主要用途
必须核对的内容
ACT_RE_MODEL
模型编辑
模型内容与关联信息
ACT_RE_DEPLOYMENT
部署批次
发布记录存在
ACT_RE_PROCDEF
可执行定义
key、版本、激活状态
ACT_GE_BYTEARRAY
二进制资源
内容存在且可解析
平台定义信息表
业务配置与发布元信息
主键、版本与引擎身份

历史问题中,模型与字节资源仍能导入,部署与定义却消失了。根因是转换器清理 MySQL 引擎选项
 时使用过宽规则,误命中了 INSERT 中的 ENGINE_VERSION_。

结果不是一次显式 SQL 报错,而是转换产物缺失关键数据。这说明“转换脚本执行成功”需要额外的
 数据门禁支持。

包装层已把清理范围限制在建表选项行,并检查源数据中存在的流程仓库 INSERT 是否在目标产物中
 保留。

2. 保留资源后,还要校准新增 ID

历史数据通常使用显式 ID 导入,序列却维护独立状态。若以批量 INSERT 首条 ID 推算序列起点,
 新数据很容易撞上已有记录。

实验记录中,平台流程定义信息表最大 ID 为 1020,而序列处于较小值,第一次发布出现主键冲突
 。

包装层在所有显式 ID 导入后,根据整数 ID 表的最大值生成序列校准。当前代码只针对存在对应序
 列、且主键符合整数规则的表。

def opengauss_sequence_recalibration(schema: str, converted: str) -> str:    sequence_names = {        match.group(1).lower()        for match in re.finditer(            r"(?im)^CREATE\s+SEQUENCE\s+([a-zA-Z0-9_]+_seq)\b", converted        )    }    id_tables = {        table        for table, block in table_blocks(schema).items()        if re.search(            r"(?im)^\s*`id`\s+(?:bigint|int|integer|smallint|tinyint)\b",            block,        )    }    tables = sorted(        table for table in id_tables if f"{table}_seq" in sequence_names    )    lines = ["-- Recalibrate PostgreSQL-family sequences after all explicit-ID imports."]    lines.extend(        f"SELECT setval('{table}_seq', "        f"COALESCE((SELECT MAX(id) FROM {table}), 0) + 1, false);"        for table in tables    )    return "\n".join(lines)

MAX(id)+1 配合 is_called=false,使下一次取号使用指定值。若现场另有并发写入、负步长序
 列或特殊起点,需要按实际情况检查,不能把导入后校准当成在线运行时的常规操作。

文本主键表不应被强行套上数值序列规则。迁移中保留主键语义,比“所有表都用同一种 ID 策略”更
 重要。

3. 用一个数值例子理解序列状态

假设整数业务表已经导入到 ID 1020,而序列仍处在较小位置。

查询旧记录没有问题,第一次发布却可能取到已经存在的 ID。

错误不在“发布动作的标题”,而在历史数据与新取号之间没有完成衔接。

当前生成器以最大值加一作为导入后的起点,并将 is_called 设置为 false。

在这个例子中,指定值为 1021,第一次取号使用 1021,随后继续递增。

若把同一个值设为已经调用过,下一次取号的结果会不同;验证时应查看序列状态,不能只看一个 l
 ast_value。

空表没有最大 ID,当前规则通过 COALESCE 从常规整数起点继续。

这不意味着所有业务都应从 1 开始:具有特定起点、步长或非整数身份的表,需要自己的规则。

同时,序列取号不应被当成连续业务编号。事务失败可能留下编号间隙,业务单号是否连续属于另一
 个领域要求。

身份
主要用途
验收重点
数据库主键
记录关联与唯一身份
不重复、类型正确
序列状态
为新增记录供号
与已导入数据衔接
业务编号
人员识别单据
按实际编号规则生成
流程实例 ID
查询与回调定位
与业务键匹配

把这几种身份分开,能避免用“重排业务编号”处理主键冲突,也能避免把正常序列间隙误判成丢数据
 。

五、让登录、发布与填报成为一条回归路径

▲ 先连接目标库,再读取模型与部署资源,发布时取得新 ID,最后在产品入口打开表单;完整审批是后续独立验收步骤。

设计决策
当前做法
用户获得的结果
认证配对
官方 openGauss JDBC
后端建立有效连接
日志依赖
保留驱动与 SPI 的白名单
应用可正常启动
引擎识别
产品名映射 postgres
流程引擎选择匹配 SQL
仓库完整性
源 / 目标 INSERT 门禁
发布资源不会静默消失
序列
导入后按实际 MAX 校准
发布与新增不撞历史 ID

1. 历史实验记录明确到哪一步

验证项
openGauss 5.0.0 结果
结论范围
数据库运行
服务启动
数据库运行时可用
表导入
783 张表,含兼容表 dual
782 张源表覆盖
用户数据
72 条用户记录
指定基线数据存在
流程资源
二进制记录核对通过
资源导入具备证据
应用
健康检查 UP
应用完成启动
产品
登录、工作台、OA 菜单
基础产品入口可用
用印
可填报到最终提交前
填报通过,完整审批未定为通过项

测试记录中的状态不能靠另一数据库的通过项补齐。PostgreSQL 16 完成审批,可以帮助定位 PG 路
 径差异,却不能代替 openGauss 上的同一业务验证。

2. 新环境应该继续验证什么

现场下一步是用获准测试账号提交代表申请,检查任务产生、各级审批和业务回写。再按客户范围补
 附件、批量查询、报表与导出。

特别是使用 FIND_IN_SET、日期函数或窗口函数的运行时 SQL,需要按对应模块验证。初始化 SQL
 转换器不会扫描并修复 Java 中的全部业务查询。

如果某页正常而某页失败,应将失败请求、SQL、驱动与 schema 关联起来,先确认问题落在哪一层
 ,再决定修改。

六、openGauss 与 PostgreSQL 对照的正确用法

两者在实验室使用独立数据库与独立 Profile。openGauss 使用自己的 JDBC 驱动和 PG 兼容模式;
 PostgreSQL 使用官方 PostgreSQL 驱动,并原生被 Flowable 识别。

实验室 PostgreSQL 实际端口为 5434,因为 openGauss 已占用 5432 / 5433。计划中的端口不能替
 代最终安装记录。

对照项
openGauss
PostgreSQL
驱动
org.opengauss.Driver org.postgresql.Driver
JDBC 前缀
jdbc:opengauss: jdbc:postgresql:
建库兼容模式
PG
无该兼容模式参数
Flowable 类型
需要产品名映射
原生识别
本轮代表业务
登录与填报
用印审批闭环

PostgreSQL 是兼容对照,不归为国产数据库,也不能给人大金仓或 openGauss 自动授予通过状态。

以流程发布为例:一张定位卡怎样穿过五层技术栈

假设管理员已经登录,但发布一个已有模型时失败。

这条现象涉及的范围比“应用起不来”更窄,应保留发布请求和首个错误,再逐层核对。

第一层:目标环境身份

先确认当前 Profile 与 JDBC URL,确保确实连接 openGauss。

再确认数据库版本、schema 与应用版本。

如果测试人员以为在 openGauss,实际启动的却是 PostgreSQL 实例,后续对照没有意义。

环境身份确认后,不再重复检查与当前失败无关的操作系统安装过程。

第二层:有效连接与日志

工作台能查询,通常说明至少存在有效连接;仍要核对发布请求使用的数据源。

如果连接认证失败,查看官方驱动与认证组合,不把错误泛化成 SQL 方言问题。

如果服务在发布前已因日志依赖异常退出,则先检查类路径和打包结果。

相同“发布失败”的页面提示,可能对应完全不同的后端阶段。

第三层:模型与资源身份

模型 ID 指向编辑对象,流程 key 指向业务定义,部署 ID 指向一次发布。

不要把三个身份当成同一字段。

核对模型内容可读,再查看是否有部署与激活定义。

若转换产物缺失定义 INSERT,应在转换输入与规则层修正,重新生成目标资产,而非在运行时造一
 条空定义。

第四层:新增主键路径

发布可能插入平台定义信息与引擎记录,因此只读查询正常不能排除主键问题。

先观察报错的具体表和约束,再检查该表是否使用序列、序列是否配套、历史最大值是多少。

序列校准应在导入结束后、应用写入前完成。

应用正在并发写入时,不应随意重设序列来尝试“修好这一次发布”。

如果报错表采用字符串 ID,也不能套用整数序列方案。

第五层:产品入口结果

发布成功后,重新检查发起入口与对应业务表单。

定义已存在但入口不可见,可能涉及发起权限和菜单配置。

入口可见但表单打开失败,可能涉及表单绑定、业务 API 和字段契约。

它们都不是“再次发布模型”一定能解决的问题。

失败位置
优先观察的事实
合理处理层
认证
驱动、模式、账号
JDBC 与参数
日志初始化
冲突类与包内容
Maven 打包
找不到定义
key、deployment、procdef
初始化与发布资产
主键冲突
表、约束、序列状态
导入后校准
入口不可见
定义状态、发起权限
业务配置
表单失败
绑定身份、接口结果
表单与业务 API

为什么不要先做全局“兼容补丁”

一个特定模型、数据包或配置的问题,应该先修它的来源。

若为了让页面暂时打开而在通用加载中补别名或改匹配,后续模型可能一起受到影响。

数据库迁移也是如此:错误数据不应被公共查询层自动改写成另一种身份。

只有明确根因属于公共方言或引擎识别,才扩大到公共配置,并验证原有数据库路径。

哪些结果可以记录为本次新增证据

登录通过,只提升登录状态。

发布通过,只提升对应模型发布状态。

填写表单正常,只提升填报状态。

提交和审批没有执行时,继续保持未测试,而不是把整条流程统一标成通过。

观察项
最少保留的证据
环境
版本、Profile、schema
发布
模型身份、定义 key、发布结果
主键
目标表与实际取号路径
产品
对应入口与字段观察
边界
未执行步骤与后续安排

这张定位卡让问题沿着真实依赖关系收敛,也让后续验收结论只覆盖本次实际取得的结果。


常见问题(FAQ)

openGauss 能直接使用 PostgreSQL 驱动吗?

应以指定版本和认证方式实测。本文实验组合在 PostgreSQL JDBC 认证路径遇到问题,最终使用 op
 enGauss 官方驱动。

为什么只保留官方驱动包的一部分内容?

当前包内嵌旧版日志类。工程保留驱动实现与 JDBC SPI,并排除整包再次进入 Boot 产物,避免日
 志依赖冲突。

模型迁移了,发起入口为什么还为空?

还需核对部署、可执行定义、资源及激活状态。模型是设计资产,不能独立代表已发布的运行资产。

openGauss 已经通过完整用印审批吗?

本文采用的历史最终证据到用印填报阶段。完整审批需要在对应 openGauss 环境继续验证,不能沿
 用达梦或 PostgreSQL 的结果。

结语:兼容关系要通过产品路径解释

openGauss 接入不是一个 URL 的变化,而是驱动、依赖、引擎识别、发布资源和新数据主键共同保
 持一致。

RuoYi Office 把这些差异固化在专用配置与可复用工具中,使登录、发布和填报可以成为连续回归
 路径。客户关心的页面因此有了对应技术依据,工程人员也能明确后续还要验收什么。

迁移时,你会先查模型数量,还是先查部署、流程定义和序列状态?这几项的顺序,往往能节省不少
 定位时间。


打开演示地址直接查看系统。

【声明】内容源于网络
0
0
企业软件源码
RuoyiOffice 是一套基于 Spring Boot + Vue3 +Uniapp 的企业一体化管理平台,集 OA、CRM、ERP、工作流、HR、资产、合同、项目、AI应用等业务于一体,帮助企业用一个系统协同管理多类核心业务。
内容 175
粉丝 0
企业软件源码 RuoyiOffice 是一套基于 Spring Boot + Vue3 +Uniapp 的企业一体化管理平台,集 OA、CRM、ERP、工作流、HR、资产、合同、项目、AI应用等业务于一体,帮助企业用一个系统协同管理多类核心业务。
总阅读4.2k
粉丝0
内容175