一个html实现数据库自定义查询

article/2025/6/8 5:25:21

使用场景

应用上线后甲方频繁的找开发查询数据库数据,且没有固定的查询规律,产品经理也没有规划报表需求。

实现方案

后端开放自定义sql查询,屏蔽所有数据库的高危操作,将常用查询的sql放在一个html中的js中直接查询,功能满足以下需求:

  • 可动态设置接口地址,方便查看测试和正式数据库
  • 可预设常用查询sql
  • 支持cte查询,支持sql注释
  • 动态表头,分页显示总条数
  • 保留查询历史记录
  • 预览长文本支持单机常看详情
  • 最重要的,尽量简单,单页面实现,无其他依赖

效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实现代码

后端java接口

	@Autowiredprivate JdbcTemplate jdbcTemplate;@PostMapping("/query/sql/page")@Operation(summary = "通用SQL分页查询", description = "仅允许执行SELECT语句并支持分页")public ResponseResult<PageResponse> executePagedQuery(@RequestBody SqlQueryRequest request) {String sql = request.getSql();Integer pageSize = request.getPageSize();Integer pageIndex = request.getPageIndex();try {// 校验参数if (sql == null || sql.trim().isEmpty() || !isSafeSelectSql(sql)) {return ResponseResult.fail(400, "无效的SQL语句或非SELECT查询");}if (pageSize == null || pageSize <= 0) {pageSize = 10;}if (pageIndex == null || pageIndex < 1) {pageIndex = 1;}// 构建 count SQL// 修改 executePagedQuery 方法中调用 buildCountSql 的部分:String safeSql = removeSingleLineComments(sql);String countSql = buildCountSql(safeSql);// 执行 count 查询Long total = jdbcTemplate.queryForObject(countSql, Long.class);// 添加分页条件String pagedSql = safeSql + " LIMIT " + pageSize + " OFFSET " + ((pageIndex - 1) * pageSize);// 执行分页查询List<Map<String, Object>> result = jdbcTemplate.queryForList(pagedSql);// 返回分页结果return ResponseResult.success(PageResponse.of(result, total, pageIndex, pageSize));} catch (Exception e) {log.error("执行分页SQL失败: {}", e.getMessage(), e);return ResponseResult.fail(500, "SQL执行异常:" + e.getMessage());}}// 构建 COUNT SQLprivate String buildCountSql(String originalSql) {return "SELECT COUNT(*) FROM (" + originalSql + ") AS tmp";}/*** 移除 SQL 中的单行注释(以 "--" 开头的部分)*/private String removeSingleLineComments(String sql) {if (sql == null) {return null;}// 使用正则表达式匹配 "--" 注释并移除整行return sql.replaceAll("--[^\n]*", "");}/*** 判断是否为安全的 SELECT 查询(支持 CTE)*/private boolean isSafeSelectSql(String sql) {if (sql == null || sql.trim().isEmpty()) {return false;}String trimmedSql = sql.trim().toLowerCase();// 使用正则判断是否是以 SELECT 或 WITH 开头,并且不包含危险关键词return trimmedSql.matches("(?s:^(select|with).*$)")&& !containsForbiddenKeywords(trimmedSql);}/*** 检查 SQL 是否包含非法关键字*/private boolean containsForbiddenKeywords(String sql) {List<String> forbiddenKeywords = Arrays.asList("\\b(delete|update|insert|drop|truncate|merge|exec|execute|create|alter|grant|revoke|call|load|replace|upsert|copy)\\b","into","for update");for (String pattern : forbiddenKeywords) {if (Pattern.compile(pattern, Pattern.CASE_INSENSITIVE).matcher(sql).find()) {return true;}}return false;}

为了解决跨域问题,还需要添加如下代码

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/test/**")     // 允许跨域的路径.allowedOrigins("*")       // 允许所有来源.allowedMethods("GET", "POST", "PUT", "OPTIONS").allowedHeaders("*")       // 允许所有头部.exposedHeaders("*").allowCredentials(false)    // 关闭凭据支持.maxAge(3600);             // 预检请求的有效期}
}

单页面

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"/><title>通用SQL查询页面</title><!-- 引入 Element Plus 样式 --><link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css"/><style>body {margin: 20px;}.form-container {margin-bottom: 20px;}.table-wrapper {max-height: 500px;overflow-y: auto;}.split-container {display: flex;gap: 20px;}.left-panel {flex: 1;}.right-panel {margin-top: 1rem;width: 100px;display: flex;flex-direction: column;gap: 15px;align-items: center;}</style>
</head>
<body>
<div id="app"><!-- SQL 查询表单 --><el-card class="form-container"><el-form label-position="top" :model="form" @submit.prevent="fetchData"><div class="split-container"><!-- 左边 SQL 输入区 --><div class="left-panel"><el-form-item label="SQL语句" style="margin-bottom: 0;"><template #label>SQL语句<span style="color: red; font-size: 12px; margin-left: 10px;">(不可输入任何修改和删除相关的语句)</span><span style="color: #00d28c; font-size: 12px; margin-left: 10px;">(“--” 可以忽略单行语句,移除可添加筛选条件)</span></template><el-input v-model="form.sql" type="textarea" rows="8" placeholder="请输入SQL语句"></el-input></el-form-item></div><!-- 右边参数+按钮 --><div class="right-panel"><el-button type="primary" @click="showApiRootDialog = true" style="width: 100%;">接口地址</el-button><!-- 内置查询按钮 --><el-popover placement="left" trigger="click" width="250px"><template #reference><el-button type="primary" style="width: 100%;">内置查询</el-button></template><div><h4 style="margin-top: 0;">预设查询列表</h4><ul style="list-style: none; padding-left: 0;"><li v-for="(preset, index) in presetQueries" :key="index"><el-link @click="usePresetQuery(preset)" type="primary">{{ preset.name }}</el-link></li></ul></div></el-popover><!-- 历史按钮 --><el-button plain @click="showHistoryDialog = true" style="width: 100%;">历史查询</el-button><!-- 查询按钮 --><el-button type="success" native-type="submit" style="width: 100%;">查询</el-button></div></div></el-form></el-card><!-- 表格展示 --><el-table :data="tableData" border class="table-wrapper" v-loading="loading"><el-table-column v-for="(col, index) in columns" :key="index" :label="col"><template #default="scope"><span:title="scope.row[col]"@click="showFullContentDialog(scope.row[col])"style="display: inline-block; max-width: 300px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;">{{ scope.row[col] }}</span></template></el-table-column></el-table><!-- 查看完整内容弹窗 --><el-dialog v-model="showContentDialog" title="完整内容" width="60%"><pre style="white-space: pre-wrap; word-wrap: break-word;">{{ fullContent }}</pre></el-dialog><!-- 分页组件 --><div style="display: flex; justify-content: flex-end; align-items: center; margin-top: 20px;"><span style="margin-right: 15px; font-size: 14px;">共 {{ pageInfo.total }} 条</span><el-paginationlayout="prev, pager, next":total="pageInfo.total"v-model:current-page="form.pageIndex":page-size="form.pageSize"@current-change="handlePageChange"background/></div><!-- 接口设置弹窗 --><el-dialog v-model="showApiRootDialog" title="api设置"><el-form label-position="top"><!-- 接口地址 --><el-form-item label="后端接口地址"><el-input v-model="apiUrl" placeholder="请输入后端接口地址"></el-input></el-form-item><!-- 每页条数 + 历史缓存条数 并排布局 --><div style="display: flex; gap: 10px;"><el-form-item label="每页条数" style="flex: 1;"><el-input-number v-model="form.pageSize" :min="1" :max="100" style="width: 100%;"></el-input-number></el-form-item><el-form-item label="历史缓存条数" style="flex: 1;"><el-input-number v-model="historyCacheSize" :min="1" :max="50" style="width: 100%;"></el-input-number></el-form-item></div></el-form><template #footer><el-button @click="showApiRootDialog = false">取消</el-button><el-button type="primary" @click="saveRootPath">确定</el-button></template></el-dialog><!-- 历史记录弹窗 --><el-dialog v-model="showHistoryDialog" title="历史查询记录"><el-scrollbar style="height: 300px;"><ul style="list-style: none; padding-left: 0; margin: 0;"><li v-for="(item, index) in historyList" :key="index" style="padding: 8px 0 4px;"><el-link @click="useHistory(item)" type="primary">{{ item }}</el-link><div v-if="index < historyList.length - 1"style="border-bottom: 1px solid #eee; margin: 4px 0;"></div></li></ul></el-scrollbar><template #footer><el-button @click="clearHistory">清空历史</el-button><el-button @click="showHistoryDialog = false">关闭</el-button></template></el-dialog>
</div><!-- 引入 Vue 3 -->
<script src="https://unpkg.com/vue@3.4.15/dist/vue.global.prod.js"></script>
<!-- 引入 axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 引入 Element Plus 组件库 -->
<script src="https://unpkg.com/element-plus/dist/index.full.min.js"></script><script>const {createApp} = Vue;createApp({data() {// 预设查询const presetQueries = [{name: "设施查询", sql: "  SELECT a.id AS \"设施Id\",a.name AS \"设施名称\",bt.name AS \"设施类型\",cc.CITY_NAME AS \"城市名称\",a.PROPERTIES as \"详细属性\",a.DISTRICT AS \"区县\"\n" +"    FROM building a\n" +"     LEFT JOIN BUILDING_TYPE bt ON a.TYPE=bt.ID\n" +"     LEFT JOIN CITY_CONFIG cc ON a.city = cc.city_code\n" +"     -- where bt.name = '供水厂'"},{name: "城市信息", sql: "  SELECT city_code AS \"城市编码\",city_name AS \"城市名称\",DISTRICTS AS \"区县\",CITY_CONFIG.SMS_ENABLE AS \"短信开关\"\n" +"   FROM city_config"},{name: "指定时间区间预警数量统计", sql: "SELECT \"LEVEL\" AS \"预警等级\" ,count(1) AS \"触发次数\"\n" +"FROM FORECAST_RAIN_LOG frl  \n" +"WHERE frl.CREATE_TIME BETWEEN '2025-06-01 22:00:00.000' AND '2025-06-02 01:00:00.000' \n" +"-- AND frl.\"LEVEL\" >0\n" +"-- AND frl.RAIN_ID = 184\n" +"GROUP BY frl.LEVEL"},{name: "短信发送记录", sql: "SELECT sl.CITY_CODE AS \"城市编码\",sl.CITY_NAME AS \"城市\",TO_CHAR(sl.SEND_TIME, 'YYYY-MM-DD HH24:MI:SS') AS \"发送时间\",sl.USERNAME AS \"接收人\",sl.PHONE AS \"手机号\",sl.CONTENT AS \"短信内容\",sl.WARNING_LEVEL AS \"预警等级\"\n" +"FROM SMS_LOG sl\n" +"WHERE 1=1 \n" +"-- AND sl.CITY_NAME  = '百色市' \n" +"-- AND sl.SEND_TIME BETWEEN '2025-05-01 22:00:00.000' AND '2025-06-02 01:00:00.000'\n" +"-- AND sl.USERNAME = '黄科谕'\n" +"ORDER BY sl.SEND_TIME DESC"},{name: "设施降雨预警历史记录", sql: "SELECT \n" +"    b.id AS \"设施id\",b.name AS \"设施名称\",\n" +"    a.val AS \"降雨量\", a.LEVEL AS \"预警等级\",\n" +"    TO_CHAR(a.CREATE_TIME, 'yyyy-MM-dd HH24:mi:ss') as \"预警时间\",\n" +"    cc.CITY_NAME AS \"城市\", cc.city_code AS \"城市编码\"\n" +"FROM FORECAST_RAIN_LOG a   \n" +"LEFT JOIN building b ON a.RAIN_ID = b.id\n" +"LEFT JOIN CITY_CONFIG cc ON cc.city_code = b.city\n" +"WHERE a.create_time > '2025-06-01 09:30:00' \n" +"  AND a.create_time < '2025-06-03 14:30:30' \n" +"  AND a.level > 0\n" +"  --筛选i设施\n" +"  -- AND b.id = 826\n" +"  --筛选预警等级\n" +"  -- AND a.level = 2\n" +"ORDER BY a.CREATE_TIME ASC"},{name: "指定时间区间发生预警的设施", sql: "SELECT b.id AS \"设施id\",cc.CITY_NAME AS \"城市\",b.name AS \"设施名称\",b.PROPERTIES AS \"详细属性\"\n" +"FROM building b \n" +"LEFT JOIN CITY_CONFIG cc ON b.city = cc.CITY_CODE\n" +"WHERE b.id in (\n" +"\tSELECT DISTINCT frl.RAIN_ID  FROM FORECAST_RAIN_LOG frl \n" +"WHERE frl.\"LEVEL\" >0  AND frl.CREATE_TIME BETWEEN '2025-06-01 22:00:00.000' AND '2025-06-02 01:00:00.000' \n" +")\n" +"ORDER BY CITY_NAME"},{name: "当前触发短信预警的设施", sql: "WITH three_hour_records AS (\n" +"                SELECT\n" +"                    frl.*,\n" +"                    ROW_NUMBER() OVER (PARTITION BY frl.RAIN_ID ORDER BY frl.CREATE_TIME DESC) as rn\n" +"                FROM FORECAST_RAIN_LOG frl\n" +"                WHERE frl.DURATION = 3\n" +"                  -- 筛选最近3小时的数据\n" +"                  AND frl.CREATE_TIME >= DATEADD(HOUR, -3, SYSDATE)\n" +"            )\n" +"         -- 查询降雨预警>0且三小时内没发短信的设施\n" +"        ,constant_alert AS (\n" +"            SELECT\n" +"            t.RAIN_ID\n" +"            FROM three_hour_records t\n" +"            -- 最新预警等级大于0\n" +"            WHERE t.rn =1 and t.LEVEL > 0\n" +"            -- 且三小时内没有短信记录\n" +"            AND NOT EXISTS (\n" +"            SELECT 1 FROM SMS_LOG s\n" +"            WHERE s.SEND_TIME >= DATEADD(HOUR, -3, SYSDATE)\n" +"            AND s.building_ids LIKE '%'||t.RAIN_ID||'%'\n" +"            )\n" +"        )\n" +"        -- 检测最新预警等级大于3小时内已发短信的预警等级的设施\n" +"        ,risk_increased AS (\n" +"          SELECT\n" +"            l1.RAIN_ID\n" +"            FROM three_hour_records l1\n" +"            LEFT JOIN (\n" +"                SELECT \n" +"                    building_ids,\n" +"                    WARNING_LEVEL,\n" +"                    ROW_NUMBER() OVER (PARTITION BY building_ids ORDER BY SEND_TIME DESC) as sms_rn\n" +"                FROM SMS_LOG\n" +"                WHERE SEND_TIME >= DATEADD(HOUR, -3, SYSDATE)\n" +"            ) s ON s.building_ids LIKE '%'||l1.RAIN_ID||'%' AND s.sms_rn = 1\n" +"            WHERE l1.rn = 1\n" +"            AND l1.LEVEL > s.WARNING_LEVEL\n" +"        )\n" +"        -- 合并两类需要发送短信的设施\n" +"        SELECT\n" +"            b.id, b.city AS cityCode, c.CITY_NAME AS cityName,\n" +"            b.name, b.PROPERTIES,\n" +"            lr.CREATE_TIME AS updatedAt,\n" +"            lr.val as val,\n" +"            lr.level as level\n" +"        FROM building b\n" +"        INNER JOIN (\n" +"        \t-- 设施ID去重合并\n" +"            SELECT RAIN_ID FROM risk_increased\n" +"            UNION\n" +"            SELECT RAIN_ID FROM constant_alert\n" +"        ) combined ON b.id = combined.RAIN_ID\n" +"        INNER JOIN three_hour_records lr ON b.id = lr.RAIN_ID AND lr.rn = 1\n" +"        LEFT JOIN city_config c ON b.city = c.CITY_CODE\n" +"        -- 只给内涝设施发送短信且城市开关打开\n" +"        where b.type in (3,36) and c.sms_enable = 1"},];// 获取本地缓存的 SQL,默认为空字符串const lastSql = localStorage.getItem('lastSql') || '';// 获取默认 SQL:优先用本地缓存,否则用第一个预设 SQLconst defaultSql = lastSql || (presetQueries.length >  0 ? presetQueries[0].sql : '');return {apiUrl: localStorage.getItem('apiUrl') || 'http://192.168.10.160:9876/test/query/sql/page',form: {sql: defaultSql,pageSize: parseInt(localStorage.getItem('pageSize')) || 10,pageIndex: 1},tableData: [],columns: [],pageInfo: {total: 0,pages: 0},loading: false,presetQueries: presetQueries,// 控制弹窗showApiRootDialog: false,showHistoryDialog: false,// 历史查询historyList: JSON.parse(localStorage.getItem('historySqls') || '[]'),historyCacheSize: parseInt(localStorage.getItem('historyCacheSize')) || 10,//单元格详情fullContent: '',showContentDialog: false};},methods: {async fetchData() {this.loading = true;if (!this.apiUrl || !this.form.sql.trim()) {this.$message.warning("请填写完整的后端地址和SQL语句");this.loading = false;return;}try {const res = await axios.post(this.apiUrl, {sql: this.form.sql,pageSize: this.form.pageSize,pageIndex: this.form.pageIndex});if (res.data.code === 0 && res.data.data) {this.tableData = res.data.data.records || [];this.pageInfo.total = res.data.data.total || 0;this.pageInfo.pages = res.data.data.pages || 0;this.columns = this.tableData.length > 0 ? Object.keys(this.tableData[0]) : [];// 只有在 SQL 不同的情况下才添加历史const lastSql = localStorage.getItem('lastSql');if (this.form.sql.trim() !== (lastSql || '')) {this.addToHistory(this.form.sql);localStorage.setItem('lastSql', this.form.sql);}} else {this.$message.error(res.data.msg || '查询失败');}} catch (err) {this.$message.error('接口调用失败,请检查网络或SQL语句');console.error(err);} finally {this.loading = false;}},handlePageChange(page) {this.form.pageIndex = page;this.fetchData();},saveRootPath() {localStorage.setItem('apiUrl', this.apiUrl);localStorage.setItem('pageSize', this.form.pageSize);localStorage.setItem('historyCacheSize', this.historyCacheSize);this.showApiRootDialog = false;},useHistory(sql) {this.form.sql = sql;this.showHistoryDialog = false;this.fetchData();},showFullContentDialog(content) {this.fullContent = content;this.showContentDialog = true;},addToHistory(sql) {let index = this.historyList.indexOf(sql);if (index !== -1) {this.historyList.splice(index, 1); // 移除旧的}this.historyList.unshift(sql);// 使用 historyCacheSize 控制最大缓存条数this.historyList = this.historyList.slice(0, this.historyCacheSize);localStorage.setItem('historySqls', JSON.stringify(this.historyList));},clearHistory() {this.historyList = [];localStorage.removeItem('historySqls');},usePresetQuery(preset) {this.form.sql = preset.sql;this.fetchData(); // 可选:点击即自动查询},}}).use(ElementPlus).mount('#app');
</script>
</body>
</html>

http://www.hkcw.cn/article/qPEiLKqNkq.shtml

相关文章

[特殊字符] Unity UI 性能优化终极指南 — ScrollRect篇

ScrollRect ManualScrollRect API 我参考了官方最新文档&#xff08;基于UGUI 3.0包&#xff09;&#xff0c;加上实际性能测试经验&#xff0c;直接给你梳理&#xff1a; &#x1f3af; Unity UI 性能优化终极指南 — ScrollRect篇 &#x1f9e9; 什么是 ScrollRect&#xff…

VsCode 安装 Cline 插件并使用免费模型(例如 DeepSeek)

当前时间为 25/6/3&#xff0c;Cline 版本为 3.17.8 点击侧边栏的“扩展”图标 在搜索框中输入“Cline” 找到 Cline 插件&#xff0c;然后点击“安装” 安装完成后&#xff0c;Cline 图标会出现在 VS Code 的侧边栏中 点击 Use your own API key API Provider 选择 OpenRouter…

Spark期末基础复习

填空选择判断 第一章 一、填空题 1.Scala语言的特性包含____________、函数式编程的、____________、可扩展的、____________。 2.在Scala 数据类型层级结构的底部有两个数据类型&#xff0c;分别是____________和____________。 3.在Scala中&#xff0c;声明变量的关键字有…

【Zephyr 系列 5】定时器与低功耗控制:打造省电高效的嵌入式系统

🧠关键词:Zephyr、定时器、k_timer、PM、低功耗、STM32、RTC 📌适合人群:想实现周期任务、功耗优化、定时唤醒等功能的 MCU 工程师 ✨ 前言:省电不是选项,而是刚需 在电池供电的嵌入式设备中,功耗决定了产品寿命与可靠性。无论是蓝牙传感器、GPS 跟踪器还是 LoRa 节点…

ATR2660SGNSS L1 频段 低噪声放大器

ATR2660S是一款应用于GNSS接收机的低噪声放大器&#xff0c;芯片集成了有源偏置电路和ESD保护电路&#xff0c;核心电路部分使用两级放大器结构进一步提高功率增益。 主要特征 高增益&#xff1a; 30dB 1575.42MHz 31dB 1176.45MHz 低噪声系数&#xff1a; 1.1dB 1575.42MHz 1.…

【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(1)——Chat Client API

Spring AI框架快速入门 一、前言二、前期准备2.1 运行环境2.2 maven配置2.3 api-key申请 三、Chat Client API3.1 导入pom依赖3.2 配置application.properties文件3.3 创建 ChatClient3.3.1 使用自动配置的 ChatClient.Builder3.3.2 使用多个聊天模型 3.4 ChatClient请求3.5 Ch…

FreeRTOS的简单介绍

一、FreeRTOS介绍 FreeRTOS并不是实时操作系统&#xff0c;因为它是分时复用的 利用CubeMX快速移植 二、快速移植流程 1. 在 SYS 选项里&#xff0c;将 Debug 设为 Serial Wire &#xff0c;并且将 Timebase Source 设为 TIM2 &#xff08;其它定时器也行&#xff09;。为何…

Deepseek/cherry studio中的Latex公式复制到word中

需要将Deepseek/cherry studio中公式复制到word中&#xff0c;但是deepseek输出Latex公式&#xff0c;比如以下Latex代码段&#xff0c;需要通过Mathtype翻译才能在word中编辑。 $$\begin{aligned}H_1(k1) & H_1(k) \frac{1}{A_1} \left( Q_1 u_1(k) Q_{i1} - Q_2 u_2(k…

如何爬取google应用商店的应用分类呢?

以下是爬取Google Play商店应用包名(package name)和对应分类的完整解决方案&#xff0c;采用ScrapyPlaywright组合应对动态渲染页面&#xff0c;并处理反爬机制&#xff1a; 完整爬虫实现 1. 安装必要库 # 卸载现有安装pip uninstall playwright scrapy-playwright -y# 重新…

英福康INFICON VGC501, VGC502, VGC503 单通道、双通道和三通道测量装置

英福康INFICON VGC501, VGC502, VGC503 单通道、双通道和三通道测量装置

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…

JsonCpp 库如何集成到Visual studio

这是用于 在 C 中解析和生成 JSON 数据 的工具包&#xff0c;适合在需要与前端、网络、配置等 JSON 格式交互的 C 项目中使用。 Json&#xff08;基于JsonCpp&#xff09; 格式全称&#xff1a;JavaScript Object Notation 格式特点&#xff1a; 与开发语言无关轻量级的数据…

sourceinsight4.0不识别.cc解决办法

options—>preferences 选择 c language, 点击右边的 file types, 添加 ;*.cc即可 重新创建工程, 不仅有.cc, 还有.cc的目录结构

RNN结构扩展与改进:从简单循环网络到时间间隔网络的技术演进

本文系统介绍 RNN 结构的常见扩展与改进方案。涵盖 简单循环神经网络&#xff08;SRN&#xff09;、双向循环神经网络&#xff08;BRNN&#xff09;、深度循环神经网络&#xff08;Deep RNN&#xff09; 等多种变体&#xff0c;解析其核心架构、技术特点及应用场景&#xff0c;…

IBM DB2分布式数据库架构

一、什么是分布式数据库架构 分布式数据库架构是现代数据库系统的重要发展方向&#xff0c;特别适合处理大规模数据、高并发访问和高可用性需求的应用场景。下面我们从原理、架构模式、关键技术、实现方式和常见产品几个方面来系统讲 1、分布式数据库的基本概念与原理 1. 什…

第十三章 Java基础-特殊处理

文章目录 1.包和final2.权限修饰符和代码块3.抽象类1.包和final 2.权限修饰符和代码块 3.抽象类

Could not get unknown property ‘mUser‘ for Credentials [username: null]

最近遇到jekins打包报错&#xff1a; Could not get unknown property mUser for Credentials [username: null] of type org.gradle.internal.credentials.DefaultPasswordCredentials_Decorated。 项目使用的是gradle&#xff0c;通过pipeline打docker包&#xff1b;因为ma…

核显战3A,锐龙9000G系列CPU曝光

在刚过去不久的台北国际电脑展上&#xff0c;AMD 为大家带来了 RX 9060 XT、Radeon AI PRO R 9700 显卡以及线程撕裂者系列新品。 尽管狠活儿不少&#xff0c;但这场电脑展仍然让不少同学失望而归。 因为&#xff0c;原本预期亮相锐龙 9000G 系列桌面 APU 竟没有公布半点消息。…

[yolov11改进系列]基于yolov11引入空间通道系统注意力机制SCSA的python源码+训练源码

【SCSA介绍】 1、Spatial and Channel Synergistic Attention ​ 通道和空间注意力分别为各种下游视觉任务的特征依赖性和空间结构关系提取带来了显著的改进。虽然两者的组合更有利于发挥各自的优势&#xff0c;但通道和空间注意力之间的协同作用尚未得到充分探索&#xff0c…

穿越文件之海:Linux链接与库的奇幻旅程,软硬连接与动静态库

文章目录 引言1、软硬链接1.1、基本认知1.2、实现原理1.3、应用场景1.4、取消链接1.5、ACM时间 2、动静态库2.1、认识库2.2、库的作用 3、制作静态库3.2、静态库的使用 4、制作动态库4.1、动态库的打包4.3、动态库的链接原理 5、动态库知识补充 引言 在计算机的无形世界中&…