docs: 归档项目需求分析、一期开发说明书及Kingbase数据库审计报告

This commit is contained in:
wangzhibiao committed 2026-09-13 23:16:37 +08:00
1 parent 83797f9286
commit 9d053bf41f
24 files changed
+17152

No files matched your search

@@ -0,0 +1,128 @@
# RuoYi-Vue KingbaseES (人大金仓) 适配审计报告
> **审计说明**:本轮审计仅对代码与配置文件进行静态分析与兼容性评估,未修改任何工程代码文件,未执行任何 DDL/DML 操作,所有凭据敏感信息已脱敏。
---
## A. 已确认适配
1. **JDBC 驱动类已切换**
- 在 `ruoyi-admin/src/main/resources/application-druid.yml` 中,主库驱动已正确指定为人大金仓驱动:
```yaml
driverClassName: com.kingbase8.Driver
```
2. **JDBC 连接串协议与 Schema 参数已配置**
- 连接串已适配为 `jdbc:kingbase8` 协议,并显式指定了 `currentSchema=public`:
```yaml
url: jdbc:kingbase8://192.168.139.218:4321/training?currentSchema=public&useUnicode=true&characterEncoding=utf8
```
- 经网络探测,Mac 宿主机到目标数据库 `192.168.139.218:4321` 的网络端口畅通可达。
3. **依赖声明已添加**
- 根模块 `pom.xml` 的 `<dependencyManagement>` 与 `ruoyi-admin/pom.xml` 中已添加 Kingbase 驱动坐标:
```xml
<groupId>com.kingbase</groupId>
<artifactId>kingbase8</artifactId>
<version>8.6.0</version>
```
4. **业务模块 SQL 规范度较好**
- 核心业务模块 `ruoyi-train` 下的 14 个业务表 Mapper(如 `TrainStudentMapper.xml` 等)均为标准单表 CRUD 语句,未使用复杂的 MySQL 专有方言函数。
---
## B. 明确存在的问题
### 1. 本地仓库缺失 Kingbase JDBC Jar 包
- 本地 `~/.m2/repository/com/kingbase/kingbase8/8.6.0/` 目录不存在。
- 人大金仓官方商业驱动未公开发布至 Maven 中央仓库或阿里云公共镜像,导致命令行执行 Maven 命令时依赖无法解析,构建失败。
### 2. PageHelper 分页插件方言被硬编码为 MySQL
- 在 `ruoyi-admin/src/main/resources/application.yml` 中明确配置了:
```yaml
pagehelper:
helperDialect: mysql
```
- 强制指定 `mysql` 方言会导致 PageHelper 加载 `MySqlDialect`,而非 Kingbase/PostgreSQL 专属分页与 Count 优化器,埋下深层分页与嵌套查询隐患。
### 3. Mapper XML 中存在反引号(`)转义
- PostgreSQL/Kingbase 识别双引号 `"` 作为标识符定界符,**反引号属于非法语法**。
- `ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml` 中共有 6 处使用了反引号字段 `` `query` ``(如第 32、53、59、78、149、173 行),执行对应菜单查询/更新 SQL 时将直接抛出语法错误。
### 4. Mapper XML 中包含 MySQL 专属函数
- **`date_format(...)`(共 14 处)**:
- 涉及:`SysUserMapper.xml`、`SysJobLogMapper.xml`、`SysOperLogMapper.xml`、`SysLogininforMapper.xml`、`GenTableMapper.xml`。
- 典型语法:`AND date_format(create_time,'%Y%m%d') >= date_format(#{params.beginTime},'%Y%m%d')`。
- Kingbase 中无原生 `date_format`,标准函数为 `TO_CHAR(...)`。带时间范围检索的列表查询将直接报错。
- **`find_in_set(...)`(共 3 处)**:
- 涉及:`SysUserMapper.xml`(部门权限关联)与 `SysDeptMapper.xml`(部门树父子过滤)。
- Kingbase/PG 无原生 `find_in_set` 函数,涉及组织架构层级查询时将抛出异常。
- **`ifnull(...)`(共 4 处)**:
- 涉及:`SysMenuMapper.xml` 中的 `ifnull(perms, '')`。
- PG 标准函数为 `COALESCE`。若 Kingbase 处于非兼容模式,会提示函数不存在。
### 5. 若依代码生成器(ruoyi-generator)完全无法使用
- **表元数据查询失败** (`GenTableMapper.xml`):
- 查询语句:`from information_schema.tables where table_schema = (select current_database())`。
- Kingbase 的 `current_database()` 返回数据库名(如 `training`),与 schema 名(如 `public`)不一致,无法检索出任何表。
- 查询列中的 `table_comment`、`create_time`、`update_time` 在 Kingbase 的 `information_schema.tables` 视图中并不存在,直接报列不存在异常。
- **字段元数据查询失败** (`GenTableColumnMapper.xml`):
- 包含非标准操作符 `&&`(PG 中必须用 `AND`)。
- 使用了 MySQL 专有的 `column_key`、`extra`、`column_comment`、`column_type` 字段,在 Kingbase 中不可用。
- **代码生成模板中的 MySQL 专有语法** (`vm/sql/sql.vm`):
- 包含了 `SELECT @parentId := LAST_INSERT_ID();` 及 `@parentId` 变量,Kingbase 无法解析执行。
### 6. 初始化 SQL 脚本完全未做 Kingbase 迁移
- `sql/ry_20250522.sql` 和 `sql/quartz.sql` 均为纯 MySQL 语法。
- 包含 `engine=innodb`、`auto_increment`、`bigint(20)`、`datetime`、`sysdate()`、`blob` 等 MySQL 专有 DDL 与函数,且未创建任何序列(Sequence),在 Kingbase 中无法直接执行初始化。
---
## C. 潜在风险
1. **Druid 连接保活查询配置风险**
- `application-druid.yml` 中配置了 `validationQuery: SELECT 1 FROM DUAL`。
- Kingbase 在默认或 PG 模式下并无 `DUAL` 虚拟表(仅 Oracle 兼容模式或手工建视图才有),通用保活语句应为 `SELECT 1`。
2. **Druid WallFilter(SQL 防火墙)误拦截**
- `application-druid.yml` 启用了 `filter.wall`,但未配置 Kingbase/PostgreSQL 专属的 WallFilter 白名单规则。Druid 内置 SQL 解析器在解析国产库特有语法时极易抛出 `SQLSyntaxErrorException: druid wall filter sql error`。
3. **pom.xml 构建插件硬编码 Windows 路径**
- `pom.xml` 和 `ruoyi-admin/pom.xml` 中的 `maven-dependency-plugin` 包含了写死的路径:
`<outputDirectory>D:\maven_repository\com\kingbase\kingbase8\8.6.0</outputDirectory>`。
- 在 macOS 或 Linux 打包部署时将导致构建阶段报错或路径异常。
4. **MySQL JDBC 驱动残留**
- `ruoyi-admin/pom.xml` 中仍声明有 `mysql-connector-java`,易引起类加载冗余或驱动加载冲突。
5. **Schema 硬编码不一致**
- `SysUserMapper.xml` 与 `SysConfigMapper.xml` 中部分 SQL 被硬编码加入了 `public.` 前缀,而其余所有 Mapper 均未带前缀。一旦未来生产环境数据库 schema 迁移或变更,将导致部分 SQL 跨 schema 访问失效。
6. **标识符大小写与 LIKE 模糊匹配规则差异**
- MySQL 对表名、列名以及 `LIKE` 匹配默认不区分大小写,而 Kingbase/PG 默认区分大小写(`LIKE` 严格匹配大小写,需用 `ILIKE` 或 `lower()` 处理)。若数据库中存在大小写敏感数据,前端模糊搜索可能出现遗漏。
---
## D. 后续建议
1. **建立本地/私服 Kingbase 依赖规范**
- 通过 `mvn install:install-file` 将 `kingbase8-8.6.0.jar` 安装至本地仓库,或上传至团队私有 Nexus 镜像库。
- 清理 `pom.xml` 中残留的 `mysql-connector-java` 与硬编码的 `D:\` 路径插件。
2. **修正数据源与连接池配置**
- 将 `validationQuery` 修改为标准跨库通用的 `SELECT 1`。
- 将 PageHelper 的 `helperDialect` 修正为自动识别或 `kingbase` / `postgresql`。
- 如果遇到 Druid 报防火墙拦截错误,调整 WallFilter 配置或针对 Kingbase 禁用 WallFilter。
3. **统一定义或兼容 SQL 函数**
- 方式一(推荐):修改 Mapper XML,将 `date_format` 替换为 `to_char`,反引号替换为双引号,`find_in_set` 替换为数组/字符串函数或子查询。
- 方式二:在 Kingbase 数据库的 public schema 下自定义创建 `date_format`、`find_in_set`、`ifnull` 兼容函数,降低改动范围。
4. **改造代码生成器元数据查询**
- 重构 `GenTableMapper.xml` 与 `GenTableColumnMapper.xml`,使用 `information_schema.tables` 配合 PostgreSQL 系统目录 `pg_class`、`pg_description`、`pg_attribute` 读取表及字段元数据。
---
## E. 开始业务开发前必须解决的问题(阻断级 Checklist)
| 序号 | 优先级 | 类别 | 阻断问题与解决要点 |
| :--- | :--- | :--- | :--- |
| **1** | 🔴 P0 | 依赖构建 | **安装 Kingbase JDBC Jar**:在开发机执行 `mvn install:install-file` 导入 `kingbase8-8.6.0.jar`,确保编译构建通过。 |
| **2** | 🔴 P0 | 配置项 | **纠正 PageHelper 方言**:移除 `application.yml` 中的 `helperDialect: mysql`,避免分页 SQL 生成异常。 |
| **3** | 🔴 P0 | SQL 语法 | **消除 Mapper XML 中的反引号**:修改 `SysMenuMapper.xml` 中的 `` `query` ``,避免系统菜单相关接口直接崩溃。 |
| **4** | 🔴 P0 | SQL 函数 | **解决 `find_in_set` 与 `date_format`**:在数据库端创建兼容函数,或在 `SysUserMapper.xml`、`SysDeptMapper.xml` 等核心 XML 中重写对应 SQL,否则用户管理、部门管理、时间检索必定报错。 |
| **5** | 🔴 P0 | 初始化数据 | **准备 Kingbase 版基础 DDL 脚本**:当前项目中的 `sql/ry_*.sql` 无法在 Kingbase 跑通,需提供适配 Kingbase 语法的主键序列及数据初始化脚本。 |
| **6** | 🟡 P1 | 代码生成 | **修复代码生成器元数据 SQL**:若业务开发需要使用若依代码生成器,必须先重写 `ruoyi-generator` 的元数据查询 SQL。 |
+168
View File
@@ -0,0 +1,168 @@
# RuoYi-Vue KingbaseES (人大金仓) 事实核验报告
> **核验原则**:本轮核验基于 POM 静态解析、本地环境探测与语法特征比对,未修改任何工程文件与配置,未执行任何 DDL/DML,未输出任何密码凭据。
---
## 一、PageHelper 版本与配置核验
### 1. 精确版本
- **`pagehelper-spring-boot-starter`**: **`1.4.7`**
- 其默认传递依赖的 core **`pagehelper`**: **`5.3.3`**
### 2. 继承与依赖链路
- **属性定义**:父工程 [pom.xml](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/RuoYi-Vue/pom.xml#L27) 中定义:
```xml
<pagehelper.boot.version>1.4.7</pagehelper.boot.version>
```
- **依赖管控**:父工程 [pom.xml](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/RuoYi-Vue/pom.xml#L119-L123) 的 `<dependencyManagement>` 声明:
```xml
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.boot.version}</version>
</dependency>
```
- **模块引入**:子模块 [ruoyi-common/pom.xml](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/RuoYi-Vue/ruoyi-common/pom.xml#L39-L42) 显式引入(省略版本,继承自父 POM):
```xml
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
```
- `ruoyi-framework` 和 `ruoyi-admin` 通过依赖 `ruoyi-common` 间接获得该 starter。
### 3. application.yml 当前完整 PageHelper 配置
在 [ruoyi-admin/src/main/resources/application.yml](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/RuoYi-Vue/ruoyi-admin/src/main/resources/application.yml#L109-L114) 中:
```yaml
# PageHelper分页插件
pagehelper:
helperDialect: mysql
supportMethodsArguments: true
params: count=countSql
```
---
## 二、Kingbase Maven 依赖设计与仓库核验
### 1. 所有 POM 中的 Kingbase 坐标
- 父工程 [pom.xml](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/RuoYi-Vue/pom.xml#L191-L195)(`<dependencyManagement>`):
```xml
<dependency>
<groupId>com.kingbase</groupId>
<artifactId>kingbase8</artifactId>
<version>8.6.0</version>
</dependency>
```
- 子模块 [ruoyi-admin/pom.xml](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/RuoYi-Vue/ruoyi-admin/pom.xml#L40-L44):
```xml
<dependency>
<groupId>com.kingbase</groupId>
<artifactId>kingbase8</artifactId>
<version>8.6.0</version>
</dependency>
```
### 2. 仓库配置(Repositories & PluginRepositories)
全项目所有 POM 中仅在根 [pom.xml](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/RuoYi-Vue/pom.xml#L331-L354) 配置了阿里云公共镜像:
- `<repository>`: `https://maven.aliyun.com/repository/public` (ID: `public`)
- `<pluginRepository>`: `https://maven.aliyun.com/repository/public` (ID: `public`)
### 3. ~/.m2/settings.xml 与私有仓库
- `~/.m2/settings.xml` 文件:**不存在**。
- 项目中 **未配置任何 Nexus、Artifactory 或企业私有 Maven 仓库**。
### 4. maven-dependency-plugin 完整 Execution 节点
在父工程 [pom.xml](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/RuoYi-Vue/pom.xml#L280-L304) 与 [ruoyi-admin/pom.xml](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/RuoYi-Vue/ruoyi-admin/pom.xml#L104-L129) 中均存在如下完整配置:
```xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- 输出目录 -->
<outputDirectory>D:\maven_repository\com\kingbase\kingbase8\8.6.0</outputDirectory>
<!-- 包含运行时依赖 -->
<includeScope>runtime</includeScope>
<!-- 包含编译时依赖 -->
<includeScope>compile</includeScope>
<!-- 可选:包含指定的 groupId -->
<includeGroupIds>com.kingbase</includeGroupIds>
<!-- 可选:包含指定的 artifactId -->
<includeArtifactIds>kingbase8</includeArtifactIds>
</configuration>
</execution>
</executions>
</plugin>
```
### 5. 为何使用 `com.kingbase:kingbase8:8.6.0`
- **交付与部署习惯**:人大金仓商业安装包自带的驱动文件通常命名为 `kingbase8-8.6.0.jar`。在国企信创标准交付中,官方推荐通过命令行将其安装至本地 Maven 仓库:
`mvn install:install-file -Dfile=kingbase8-8.6.0.jar -DgroupId=com.kingbase -DartifactId=kingbase8 -Dversion=8.6.0 -Dpackaging=jar`
- **开发者环境痕迹**:原工程作者在 Windows 环境(`D:\maven_repository`)下开发,采用离线介质手动安装,未通过企业 Nexus 私服托管。因此代码中固定约定了该标准坐标。
---
## 三、数据库客户端工具与模式查询获取条件
### 1. 本机客户端工具排查
- **`ksql`**:未安装(`which ksql` 返回 not found)。
- **`psql`**:未安装(`which psql` 返回 not found)。
- **`DataGrip CLI`**:未安装(系统无相关命令行软链接)。
- **其他连接工具**:Python 未安装 `psycopg2` / `asyncpg`,且无任何直接可用的数据库 CLI 工具。
### 2. 是否能直接执行 `SHOW database_mode;`
- **结论:目前无法直接执行**。
- **原因**:本机缺少连接 KingbaseES 所需的交互式 CLI 客户端工具;在未配置工具且不修改环境的前提下,无法向远程数据库发送查询指令。
---
## 四、审计项重新分类(基于数据库兼容模式视角)
> KingbaseES V8R6 具备 **Oracle**、**PostgreSQL (PG)**、**MySQL** 三种兼容器模式。不同模式下的内置函数、引号解析规则存在显著差异。
### 1. CONFIRMED(不依赖 database_mode 也确定存在的问题)
- **本地缺失 Kingbase 驱动 Jar**:本地 Maven 仓库确实不存在对应 jar 包,公网仓库无此包,阻断 Maven 编译构建。
- **构建插件硬编码 Windows 绝对路径**:`D:\maven_repository\...` 写死在 `pom.xml` 中,在 macOS/Linux 打包时必然引发异常。
- **代码生成器表名过滤逻辑缺陷 (`GenTableMapper.xml`)**:
`where table_schema = (select current_database())`。在 Kingbase 所有模式下,`current_database()` 返回的均为数据库名(如 `training`),而 `information_schema.tables.table_schema` 记录的是 schema 名(如 `public`),必然导致查不到任何表。
- **代码生成器字段元数据语法与视图缺陷 (`GenTableColumnMapper.xml`)**:
使用了非标逻辑符 `&&`;且 `column_key`、`extra`、`column_comment` 在 Kingbase 的 `information_schema.columns` 中不作为标准列存在。
### 2. MODE_DEPENDENT(是否有问题取决于 database_mode)
- **反引号(`)**(`SysMenuMapper.xml` 中的 `` `query` ``):
- 若为 **MySQL 模式**:原生支持反引号,**无问题**。
- 若为 **PG / Oracle 模式**:反引号为非法字符,**直接报错**(必须双引号 `"`)。
- **`date_format`**(14 处):
- 若为 **MySQL 模式**:支持 MySQL 日期格式化函数,**无问题**。
- 若为 **PG / Oracle 模式**:无原生 `date_format` 函数,**直接报错**(除非库内自建了兼容函数)。
- **`find_in_set`**(3 处):
- 若为 **MySQL 模式**:内置支持,**无问题**。
- 若为 **PG / Oracle 模式**:无原生函数,**直接报错**。
- **`ifnull`**(4 处):
- 若为 **MySQL 模式**:内置支持,**无问题**。
- 若为 **Oracle 模式**(主推 `nvl`)或 **PG 模式**(主推 `coalesce`):可能报错。
- **`helperDialect=mysql`**:
- 若为 **MySQL 模式**:MySQL 分页语法与机制高度吻合,**影响较小**。
- 若为 **Oracle 模式**:MySQL 分页语法(`LIMIT ? OFFSET ?`)与 Oracle 模式不兼容,**必定报错**。
- **`SELECT 1 FROM DUAL`**:
- 若为 **Oracle / MySQL 模式**:支持 `DUAL` 虚表,**完全合法可用**。
- 若为 **纯 PG 模式**:若未建 DUAL 视图则报错。
### 3. RUNTIME_TEST_REQUIRED(必须连库执行只读 SQL 才能确定)
- **实际 `database_mode` 的值**:需连库执行 `SHOW database_mode;` 才能确认到底处于何种模式。
- **远端 training 库的表是否已建好**:如果库中已有全量业务与系统表,则项目自带的初始化 SQL 无需再次执行;若为空库,则必须确认 DDL。
- **库中是否已预装兼容函数**:某些企业现场会在 public 下预建 `date_format`、`find_in_set` 标量函数。
### 4. LOW_PRIORITY(不阻塞目前业务开发的问题)
- **`GROUP_CONCAT`**:全局 Mapper XML 扫描结果为 **0 处**,实际未被使用,不构成障碍。
- **MySQL JDBC 驱动残留**:`mysql-connector-java` 虽声明但未被主数据源激活,仅有依赖冗余,不阻塞开发。
- **`public.` schema 前缀零星硬编码**:当前 JDBC URL 已配置 `currentSchema=public`,写与不写均能正确定位到 public 下的表,不影响当前运行。
- **初始化脚本为 MySQL 语法 (`sql/ry_*.sql`, `sql/quartz.sql`)**:仅影响从零全新建库,若远程开发数据库已就绪,则不影响本地业务开发。