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

这个方法的目的是检查一个给定的项目ID(projectId)是否在当前数据库中被使用(搜索全库)

  @Overridepublic Boolean existsUsedProject(Long projectId) {// 查询当前使用的库名String dataBaseName = "";dataBaseName = jdbcTemplate.queryForObject("SELECT DATABASE()", String.class);// 查询指定字段下的表名String queryTableNameSql = String.format("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS\n" +" WHERE TABLE_SCHEMA = '%s' AND COLUMN_NAME = 'project_id'", dataBaseName);List<String> tableNameList = jdbcTemplate.queryForList(queryTableNameSql, String.class);// 根据表名生成sql,并过滤不参与决策的表List<String> queryExistsSqlList = new ArrayList<>();tableNameList.removeIf(item ->ObjectUtil.equal(item, "gc_project_attr")|| ObjectUtil.equal(item, "gc_project_contract_sheet")|| ObjectUtil.equal(item, "gc_project_user")|| ObjectUtil.equal(item, "gc_store"));for (String tableName : tableNameList) {String queryExistsSql = String.format("SELECT EXISTS(SELECT 1 FROM %s where project_id = '%s' and (delete_flag is null or delete_flag = '0')  LIMIT 1)",tableName,String.valueOf(projectId));queryExistsSqlList.add(queryExistsSql);}// 拼接 union all 的sqlfinal int BATCH_SIZE = 5;for (int i = 0; i < queryExistsSqlList.size(); i += BATCH_SIZE) {// 计算当前批次的结束位置int end = Math.min(i + BATCH_SIZE, queryExistsSqlList.size());// 获取当前批次的SQL列表List<String> batch = queryExistsSqlList.subList(i, end);// 构建UNION ALL查询语句String batchSql = String.join(" \n UNION ALL \n", batch);List<String> tempExecSqlResList = jdbcTemplate.queryForList(batchSql, String.class);if (tempExecSqlResList.contains("1")) {return Boolean.TRUE;}}return Boolean.FALSE;}

这个方法的主要功能是检查指定项目ID(projectId)是否在数据库中被使用。它通过多步骤验证项目是否被关联到其他业务数据中,确保项目在删除或修改前未被引用。以下是详细逻辑:


核心步骤解析

1. 获取当前数据库名

String dataBaseName = jdbcTemplate.queryForObject("SELECT DATABASE()", String.class);

动态获取当前连接的数据库名称,用于后续系统表查询。

2. 查询包含project_id字段的所有表

String queryTableNameSql = String.format("SELECT TABLE_NAME ... AND COLUMN_NAME = 'project_id'", dataBaseName);
List<String> tableNameList = jdbcTemplate.queryForList(...);

INFORMATION_SCHEMA.COLUMNS系统表中检索当前数据库内所有包含project_id字段的表名。

3. 过滤排除表

tableNameList.removeIf(item -> ObjectUtil.equal(item, "gc_project_attr") || ... // 排除4张特定表
);

移除不参与检查的表(如gc_project_attrgc_project_contract_sheet等),这些表可能存储非核心关联数据。

4. 动态生成检查SQL

for (String tableName : tableNameList) {String sql = String.format("SELECT EXISTS(SELECT 1 FROM %s WHERE project_id='%s' AND (delete_flag IS NULL OR delete_flag='0')", ...);queryExistsSqlList.add(sql);
}

为每个表生成检查SQL:判断指定projectId是否存在且未被软删除(delete_flagnull'0')。

5. 分批次执行SQL(关键优化)

final int BATCH_SIZE = 5;
for (int i=0; i<queryExistsSqlList.size(); i+=BATCH_SIZE) {String batchSql = String.join(" \n UNION ALL \n", batch); // 每批最多5条SQL用UNION ALL合并List<String> results = jdbcTemplate.queryForList(batchSql, String.class);if (results.contains("1")) return true; // 发现引用立即返回
}

将大量SQL分批执行(每批5条),通过UNION ALL合并查询。若任意表存在关联数据(返回"1"),直接返回true

6. 最终返回
return Boolean.FALSE; // 所有检查均未找到引用

方法的核心目的

  • 防止数据误删:在删除或修改项目前,确保它未被其他业务数据关联。

  • 动态适配表结构:通过系统表自动发现所有包含project_id字段的表,无需硬编码表名。

  • 性能优化:分批次执行SQL避免数据库压力,并在发现引用后立即返回。


潜在风险

  1. SQL注入:直接拼接projectId(Long类型风险较低)和表名(来自系统表,需确保无恶意表名)。

  2. 性能问题:若包含project_id的表极多(如上百张),分批查询仍可能有性能压力。

  3. 扩展性:新增业务表时需注意是否应加入排除列表。


典型应用场景

  • 删除项目前的校验(如提示“项目已被使用,无法删除”)。

  • 修改项目关键信息前的安全校验。

http://www.dtcms.com/a/273590.html

相关文章:

  • SortByCustomOrder 根据指定的顺序对任意类型的列表进行排序
  • Python七彩花朵
  • 【实时Linux实战系列】实时系统测试与合规认证指南
  • 二刷 黑马点评 商户查询缓存
  • <script>标签对HTML文件解析过程的影响以及async和defer属性的应用
  • 在 React Three Fiber 中实现 3D 模型点击扩散波效果
  • 车企战略投资项目管理的实践与思考︱中国第一汽车集团进出口有限公司战略部投资管理专家庞博
  • 台球 PCOL:极致物理还原的网页斯诺克引擎(附源码深度解析)
  • 软件设计师中级逻辑公式题
  • Ubuntu 24.04上安装 Intelligent Pinyin 中文输入法
  • Java算法 -蓝桥云课 -卖货
  • 【联合国国家指标 2025:HDI、GDP、POP、面积】数据集countries_metric - Sheet1.csv
  • C++迭代器失效
  • 深入剖析Spring Bean生命周期:从诞生到消亡的全过程
  • 羲和:一款诗词风格的摆件App
  • GitHub Copilot:产品经理提升工作效率的AI助手
  • 销售数据可视化分析项目
  • AI基建还能投多久?高盛:2-3年不是问题,回报窗口才刚开启
  • Lookahead:Trie 树(前缀树)
  • TCP详解——流量控制、滑动窗口
  • 【接口测试】07 Fiddler使用教程(图文详解)
  • Flutter、Vue 3 和 React 在 UI 布局比较
  • 20.缓存问题与解决方案详解教程
  • 【Java】【力扣】102.二叉树层序遍历
  • 前端抓包(不启动前端项目就能进行后端调试)--whistle
  • 什么是DOM存储
  • 05 rk3568 debian11 root用户 声音服务PulseAudio不正常
  • Typecho架构深度剖析:轻量级博客系统的设计哲学与实现原理
  • 前端性能与可靠性工程:我们度量什么?核心 Web 指标与工具入门
  • 【氮化镓】不同偏压应力下电荷俘获效应导致的P-GaN HEMT阈值电压不稳定性