Jsqlparser + Freemarker + Vue3 數據透視報表設計方案

1. 目標與前置條件

目標:基于 JSQLParser + FreeMarker + Vue3 構建一套“可配置的數據透視報表”能力,實現從任意基礎 SQL/視圖出發,按維度/指標靈活聚合、篩選、排序、分頁、導出,并支持鉆取、聯動、TopN、同比環比等常見分析操作。

前置條件(結合你的技術棧)

  • 運行環境:Java 21 / Spring Boot 3.x / Spring Data / Shiro

  • 數據庫:MySQL 8.x(支持窗口函數、CTE、ROLLUP 等特性)

  • 前端:Vue3 + Element Plus(也可替換任意 UI 組件庫)

  • 模板存儲:DB(公共宏 + 業務模板),啟動時預加載 + 變更熱更新


2. 總體架構(高層)

Vue3(報表設計器/查看器)│  REST/JSON▼
Pivot API(Controller) —— 鑒權(Shiro) —— 限流/審計▼
PivotService(組裝查詢)├─ TemplateRegistry(FreeMarker 宏/模板加載與渲染)├─ SqlPipeline(JSQLParser 操作:包裹子查詢、注入條件、生成聚合)├─ QueryEngine(JdbcTemplate/EntityManager 執行 + 數據權限)└─ CacheLayer(聚合結果緩存/預聚合物化)▼MySQL 8(基礎明細表/視圖)

關鍵思想

  1. 任意 SQL → 子查詢:把用戶/模板提供的基礎 SQL 用 JSQLParser 包裝成 SELECT ... FROM ( <base_sql> ) t,統一在外層做維度聚合與篩選。

  2. 模板只關心“表達式”:維度/指標的 SQL 片段通過宏/模板生成,避免手寫大量 if/else 拼接。

  3. 強安全:白名單列/表校驗、參數化綁定、限時/限量、敏感字段脫敏、SQL 審計日志。


3. 配置模型(后端/前端統一)

{"baseSqlId": "sales_order_detail",             "dimensions": [                                  { "expr": "date_format(order_date,'%Y-%m-%d')", "alias": "d" },{ "expr": "shop_code", "alias": "shop" }],"measures": [                                    { "func": "sum", "field": "amount", "alias": "gmv", "fmt": "currency" },{ "func": "count", "field": "order_id", "alias": "orders" }],"filters": {                                     "where": [{ "expr": "order_date >= :from" },{ "expr": "order_date < :to" },{ "expr": "shop_code in (:shops)" }],"having": [ { "expr": "sum(amount) > :minGmv" } ]},"sort": [ { "by": "gmv", "dir": "desc" }, { "by": "d", "dir": "asc" } ],"limit": 100,"offset": 0,"topn": { "by": "gmv", "n": 10 },           "time": { "grain": "day" },"compare": { "yoy": true, "wow": false },     "drill": { "enabled": true, "key": "order_id" },"export": { "type": "csv" },"params": { "from": "2025-08-01", "to": "2025-09-01", "shops": ["S1","S2"], "minGmv": 1000 }
}

說明:baseSqlId 映射到一段受控的基礎 SQL(或視圖),在 TemplateRegistry/DB 中維護;前后端均以該 JSON 做協議。


4. FreeMarker 模板設計

4.1 宏(公共庫:pivot-macros.ftl

<#-- 維度渲染 -->
<#macro renderDimensions dims><#list dims as d>${d.expr} AS `${d.alias}`<#if d?has_next>,</#if></#list>
</#macro><#-- 指標渲染(支持 func(field) as alias) -->
<#macro renderMeasures ms><#list ms as m>${m.func}(${m.field}) AS `${m.alias}`<#if m?has_next>,</#if></#list>
</#macro><#-- ORDER BY -->
<#macro renderOrder sort><#if sort?? && (sort?size>0)>ORDER BY<#list sort as s>`${s.by}` ${s.dir?upper_case}<#if s?has_next>,</#if></#list></#if>
</#macro>

4.2 聚合模板(外層):pivot-aggregate.ftl

<#import "pivot-macros.ftl" as p />
SELECT<@p.renderDimensions dims=dimensions/><#if dimensions?size > 0 && measures?size > 0>,</#if><@p.renderMeasures ms=measures/>
FROM (${baseSql}
) t
<#-- WHERE 只作用于內層,通常由 SqlPipeline 注入。HAVING 用于外層聚合后過濾 -->
<#if filters?? && filters.having?? && (filters.having?size>0)>
HAVING<#list filters.having as h>${h.expr}<#if h?has_next> AND </#if></#list>
</#if>
<#if dimensions?size > 0>
GROUP BY<#list dimensions as d>${d.alias}<#if d?has_next>,</#if></#list>
</#if>
<@p.renderOrder sort=sort/>
<#if limit??> LIMIT ${limit} </#if>
<#if offset??> OFFSET ${offset} </#if>

注:baseSql 是經過 JSQLParser 處理過、帶參數的內層 SQL。


5. JSQLParser 管道(核心)

目標:把任意基礎 SQL 統一變為可注入條件的子查詢,并做安全校驗。

關鍵步驟

  1. 解析Statement stmt = CCJSqlParserUtil.parse(baseSql);

  2. 規整:移除外層 ORDER BY / LIMIT(由外層模板控制);

  3. 追加 WHERE:把 filters.where 中的條件以 AND 方式追加到內層查詢;

  4. 包裝SELECT * FROM ( <normalized_sql> ) t

  5. 白名單校驗:檢查涉及的表/列是否在白名單;

  6. 參數綁定:使用 NamedParameterJdbcTemplate 執行,避免字符串拼接。

示例工具類(片段):

public class SqlPipeline {public String wrapAsSubquery(String baseSql) {Select select = (Select) CCJSqlParserUtil.parse(baseSql);// 1) 清理外層 ORDER BY/LIMITselect.getSelectBody().accept(new OrderByAndLimitCleaner());// 2) 生成包裝 SQLString normalized = select.toString();return "SELECT * FROM (" + normalized + ") t";}public String injectWhere(String wrappedSql, List<String> whereExprs) {// whereExprs 如: ["order_date >= :from", "order_date < :to"]PlainSelect ps = (PlainSelect) ((Select) CCJSqlParserUtil.parse(wrappedSql)).getSelectBody();Expression where = ps.getWhere();for (String expr : whereExprs) {Expression e = CCJSqlParserUtil.parseCondExpression(expr);where = (where == null) ? e : new AndExpression(where, e);}ps.setWhere(where);return ps.toString();}
}

生產建議:對 parse 異常做降級(如回退到安全模式),記錄審計日志;在注入前對 expr 做黑/白名單校驗。


6. 端到端示例

6.1 基礎 SQL(注冊為 sales_order_detail

SELECTorder_id,order_date,shop_code,sku_code,qty,amount
FROM sales_order_detail

6.2 前端配置(節選)

{"baseSqlId": "sales_order_detail","dimensions": [{ "expr": "date_format(order_date,'%Y-%m-%d')", "alias": "d" },{ "expr": "shop_code", "alias": "shop" }],"measures": [{ "func": "sum", "field": "amount", "alias": "gmv" },{ "func": "count", "field": "order_id", "alias": "orders" }],"filters": {"where": [ { "expr": "order_date >= :from" }, { "expr": "order_date < :to" } ]},"sort": [ { "by": "gmv", "dir": "desc" } ],"limit": 50,"params": { "from": "2025-08-01", "to": "2025-09-01" }
}

6.3 管道出 SQL(簡化展示)

SELECTdate_format(order_date,'%Y-%m-%d') AS `d`,shop_code AS `shop`,sum(amount) AS `gmv`,count(order_id) AS `orders`
FROM (SELECT order_id, order_date, shop_code, sku_code, qty, amountFROM sales_order_detailWHERE order_date >= :from AND order_date < :to
) t
GROUP BY d, shop
ORDER BY `gmv` DESC
LIMIT 50

7. 后端實現(關鍵類與 API)

7.1 API 契約

  • POST /api/pivot/preview:入參 PivotConfig,返回渲染后的 SQL(僅開發/調試環境開放)。

  • POST /api/pivot/run:入參 PivotConfig,返回分頁數據(含列定義與格式)。

  • POST /api/pivot/export:入參 PivotConfig + export.type,流式導出 CSV/Excel。

7.2 DTO(簡化)

record Dim(String expr, String alias) {}
record Meas(String func, String field, String alias, String fmt) {}
record Filter(List<String> where, List<String> having) {}
record Sort(String by, String dir) {}record PivotConfig(String baseSqlId,List<Dim> dimensions,List<Meas> measures,Filter filters,List<Sort> sort,Integer limit,Integer offset,Map<String,Object> params
) {}

7.3 Service 關鍵流程

public PivotResult run(PivotConfig cfg) {String baseSql = templateRegistry.loadBaseSql(cfg.baseSqlId());String inner = pipeline.wrapAsSubquery(baseSql);inner = pipeline.injectWhere(inner, cfg.filters().where());String aggregated = templateRegistry.render("pivot-aggregate.ftl", Map.of("baseSql", inner,"dimensions", cfg.dimensions(),"measures", cfg.measures(),"filters", cfg.filters(),"sort", cfg.sort(),"limit", cfg.limit(),"offset", cfg.offset()));return queryEngine.query(aggregated, cfg.params());
}

7.4 數據權限建議

  • 在注入 WHERE 前,合并 data_scope 表達式(如門店/區域/用戶標簽范圍);

  • Shiro Subject → 上下文攜帶 org_ids/shop_codes

  • 對外僅暴露經過模板注冊的 baseSqlId,禁止用戶直接傳任意 SQL。


8. 性能與可用性

  1. 索引:維度列、時間列、常用過濾列建立聯合/覆蓋索引;

  2. 預聚合

    • 定時生成日/周/月粒度物化表;

    • 熱點 TopN 結果放入 Redis,配置 ttl 和“參數簽名”作為 Key;

  3. 分頁策略:聚合后分頁(LIMIT/OFFSET);統計總條數使用二次查詢:

    SELECT COUNT(1) FROM (-- 把上面 GROUP BY 的 SELECT 去掉 ORDER BY/LIMIT
    ) x
    
  4. 大結果導出:使用 fetchSize + ResultSet.TYPE_FORWARD_ONLY 流式寫 CSV;

  5. 并發:常見報表使用“參數簽名”做結果緩存(如 60s);

  6. ROLLUP:可選支持:

    SELECT d, shop, SUM(amount) gmv
    FROM t
    GROUP BY d, shop WITH ROLLUP
    

9. 高級功能示例

9.1 TopN(對店鋪按 GMV 取 Top10,其它歸為 OTHER

WITH ranked AS (SELECT shop_code, SUM(amount) gmvFROM (${baseSqlWithWhere}) tGROUP BY shop_code
), r AS (SELECT shop_code, gmv, DENSE_RANK() OVER (ORDER BY gmv DESC) rnk FROM ranked
)
SELECT IF(rnk<=10, shop_code, 'OTHER') AS shop,SUM(gmv) gmv
FROM r
GROUP BY shop

也可在外層聚合后,用窗口函數 + CASE WHEN 分桶。

9.2 同比/環比(以日粒度為例)

SELECT d,SUM(amount) AS gmv,LAG(SUM(amount)) OVER (ORDER BY d) AS gmv_prev,(SUM(amount) - LAG(SUM(amount)) OVER (ORDER BY d)) / NULLIF(LAG(SUM(amount)) OVER (ORDER BY d),0) AS wow
FROM (SELECT DATE(order_date) d, amount FROM sales_order_detail WHERE order_date BETWEEN :from AND :to
) t
GROUP BY d

YoY 可用 DATE_SUB(d, INTERVAL 1 YEAR) 關聯對比或雙區間查詢再 JOIN。

9.3 鉆取

  • 規則:每條聚合行返回一個 drillKey(如 d|shop),前端點擊發起 /api/pivot/drill?key=...,后端映射回內層 WHERE + 原始明細查詢,限制 LIMIT 1000


10. 前端(Vue3)

10.1 組件劃分

  • PivotDesigner:左側維度/指標/過濾器選擇區;

  • PivotTable:結果展示 + 匯總行 + 導出;

  • FieldCatalog:基礎 SQL 字段字典(從后端 /api/pivot/fields?baseSqlId=... 取);

10.2 關鍵代碼(示例,Composition API)

// usePivot.ts
import { ref } from 'vue'
import axios from 'axios'export function usePivot(){const config = ref({ baseSqlId: '', dimensions: [], measures: [], filters: { where:[], having:[] }, sort:[], limit:50, offset:0, params:{} })const loading = ref(false)const data = ref({ columns:[], rows:[], total:0 })async function run(){loading.value = truetry{const res = await axios.post('/api/pivot/run', config.value)data.value = res.data} finally { loading.value = false }}return { config, data, loading, run }
}
<!-- PivotTable.vue -->
<template><div><el-space><el-button :loading="loading" @click="run">運行</el-button><el-button @click="exportCsv">導出CSV</el-button></el-space><el-table :data="data.rows" style="width: 100%" :border="true"><el-table-column v-for="c in data.columns" :key="c.prop" :prop="c.prop" :label="c.label" :fixed="c.fixed" :width="c.width" /></el-table><el-paginationv-model:current-page="page"v-model:page-size="size":total="data.total"@current-change="onPageChange"@size-change="onSizeChange"/></div>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'
import { usePivot } from './usePivot'
const { config, data, loading, run } = usePivot()
const page = ref(1); const size = ref(50)
function onPageChange(p:number){ config.value.offset = (p-1)*size.value; run() }
function onSizeChange(s:number){ size.value = s; config.value.limit = s; config.value.offset = 0; run() }
function exportCsv(){ window.open('/api/pivot/export?type=csv') }
watch(()=>config.value.baseSqlId, run)
</script>

10.3 交互要點

  • 維度/指標拖拽排序即 dimensionsmeasures 順序;

  • 過濾器 UI → 生成 expr(提供字段/操作符/占位參數拼裝器,避免用戶手寫表達式);

  • 支持字段格式化:金額、百分比、千分位等(后端返回 columns[x].fmt)。


11. 安全與風控

  • 只允許調用已注冊的 baseSqlId(DB 中維護 SQL 文本與字段白名單);

  • 所有 :paramNamedParameterJdbcTemplate 綁定;

  • 表達式校驗:限制可用函數/關鍵字(例如禁止 ;, --, /* */, sleep 等);

  • 超時/行數限制:默認 timeout=15smax-rows=50,000

  • 審計:記錄用戶、SQL 摘要(hash)、耗時、掃描行數、命中緩存與否。


12. 測試計劃

  • 單測

    • JSQLParser:Where 注入、Order/LIMIT 清理、別名沖突處理;

    • 模板渲染:預期 SQL 與實際對比;

  • 集成測試

    • 常見維度組合/TopN/同比/環比/分頁/導出;

    • 大數據量性能基準(QPS、P95 延遲);

  • 回歸:每次修改模板庫后自動跑一批“黃金用例”。


13. 運維與監控

  • 暴露健康檢查與關鍵指標(查詢耗時、并發數、失敗率、緩存命中率)到 Prometheus;

  • 熱更新:DB 模板變更 → 發送 MQ(Artemis)→ 節點刷新本地緩存;

  • 失敗熔斷:同一用戶在短時內多次慢查詢/失敗,臨時降級其配額。


14. 可擴展方向

  • 預聚合引擎:按配置定時物化(增量更新);

  • 維度字典服務:統一的字段目錄/血緣追蹤;

  • 多數據源:在 baseSqlId 上綁定數據源路由;

  • 報表版本化:配置與模板版本追蹤,可回滾。


15. 落地清單(Checklist)

  • 定義 PivotConfig 協議與前端模型

  • 建立 TemplateRegistry(加載宏/模板/基礎 SQL)

  • 實現 SqlPipeline(包裝/注入/校驗)

  • 渲染聚合模板并執行(QueryEngine)

  • 前端設計器與表格組件

  • 緩存、導出、審計與告警

有了以上骨架,你可以先從“單一基礎 SQL + 2 個維度 + 2 個指標”開始最小可用版本(MVP),再迭代加入 TopN、鉆取、同比/環比等能力。


16. 模板/基礎SQL注冊與熱更新設計(結合 Artemis)

16.1 表結構(JPA 實體)

// 基礎 SQL(白名單入口)
@Entity @Table(name="pivot_base_sql")
public class PivotBaseSql extends AbstractEntity {@Id @GeneratedValue private Long id;@Comment("唯一編碼") @FormField(order=1) private String code; // 如 sales_order_detail@Lob @Comment("SQL 文本") @FormField(order=2, type="textarea") private String sqlText;@Comment("啟用狀態") private Boolean enabled = true;@Comment("允許的字段白名單(JSON)") @Lob private String fieldWhitelistJson; // ["order_id","order_date",...]@Comment("數據源標識") private String datasourceKey; // 多數據源路由@CreateByUser private Long createUserId;@Comment("版本號") private Long version;@Comment("最后修改時間") private Instant updatedAt;
}// 公共宏/模板
@Entity @Table(name="pivot_template")
public class PivotTemplate extends AbstractEntity {@Id @GeneratedValue private Long id;@Comment("類型: macro|aggregate|other") private String type;@Comment("名稱") private String name; // pivot-macros.ftl, pivot-aggregate.ftl@Lob @Comment("模板內容") private String content;@Comment("啟用") private Boolean enabled = true;private Instant updatedAt;
}

常見坑與規避

  • 內層對時間列做函數導致走不到索引 → 把函數放到外層顯示,內層只做區間過濾;

  • 維度別名與保留字沖突(如 dategroup)→ 統一反引號包裹;

  • COUNT(*)COUNT(col) 語義差異;

  • ORDER BY 字段不在 SELECT 中的 MySQL 行為差異;

  • 導出超大文件內存膨脹 → 必須流式 + 臨時文件。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/94019.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/94019.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/94019.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SpringBoot3 Ruoyi芋道管理后臺vben5.0

新技術棧&#xff08;Vue3、Vite6、TypeScript、SpringBoot3/SpringCloud基于Vben5.0最新版本&#xff0c;全面采用Vue3 Vite6 Ant Design Vue TypeScript技術棧&#xff0c;并同時支持SpringBoot3單體架構與SpringCloud微服務架構前端技術棧&#xff1a;Vue3 Vite6 TS A…

K8S - NetworkPolicy的使用

1 前置條件2 控制范圍3 隔離類型4 如何識別5 主要字段6 案例演示 前置條件 網絡策略通過網絡插件來實現。 要使用網絡策略&#xff0c;你必須使用支持 NetworkPolicy 的網絡解決方案。 創建一個 NetworkPolicy 資源對象而沒有控制器來使它生效的話&#xff0c;是沒有任何作用的…

Linux:TCP協議

TCP是一個面向連接的、可靠的、基于字節流的傳輸層協議。文次我們會通過介紹TCP的報頭并通過分析各字段的用途來進一步解釋其核心特性:可靠傳輸&#xff1a; 有確認應答、超時重傳、確保有序。流量控制和擁塞控制&#xff1a; 動態調節發送速率&#xff0c;防止丟包與擁塞。面向…

uniapp使用map打包app后自定義氣泡不顯示解決方法customCallout

前言&#xff1a;使用uniapp開發后在小程序可以正常顯示&#xff0c;但是運行打包成App后就不顯示了&#xff0c;其實這一塊對于uniapp框架開發來說&#xff0c;是有系統性的bug&#xff0c;如果你再開發時使用的是vue文件進行&#xff0c;就會出現這個問題。解決方法&#xff…

【typenum】 22 類型級別二進制對數運算(Logarithm2)

一、源碼 這段代碼實現了一個類型級別的二進制對數運算系統 定義&#xff08;type_operators.rs&#xff09; /// A **type operator** for taking the integer binary logarithm of Self. /// /// The integer binary logarighm of n is the largest integer m such /// that …

golang 非error錯誤分類

1.應用級別&#xff0c;可recover這些 panic 一般是 邏輯或使用不當導致的運行時錯誤&#xff0c;Go 程序可以用 recover 捕獲并繼續運行&#xff1a;類型示例描述類型不一致atomic.Value 存不同類型 v.Store(100); v.Store("abc")panic: store of inconsistently ty…

【Ansible】變量與敏感數據管理:Vault加密與Facts采集詳解

1. 變量Ansible利用變量存儲可重復使用的值&#xff0c;可以簡化項目的創建和維護&#xff0c;減少錯誤數量。1.1 變量名稱由字符串組成&#xff0c;必須以字母開頭&#xff0c;并且只能含有字母、數字和下劃線&#xff0c;和其它編程語言很類似。1.2 常見變量要創建的用戶要安…

ROS2下YOLO+Moveit+PCL機械臂自主避障抓取方案

整體運行架構 1.運行相機取像節點 . ./install/setup.bash ros2 launch orbbec_camera gemini_330_series.launch.py depth_registration:true 2.運行根據圖像x,y獲取z的service 基本操作記錄&#xff1a; 創建python包,在src目錄下 ros2 pkg create test_python_topic --bu…

快速入門Vue3——初體驗

目錄 前言 一、搭建環境 1.1、安裝Node.js 1.2、安裝Vite 二、項目創建 三、運行項目 四、集成Pinia 4.1、Pinia介紹 4.2、Pinia安裝 五、集成VueUse 5.1、vueuse簡介 5.2、vueuse安裝 六、集成Vant 6.1、Vant簡介 6.2、Vant安裝 前言 本專欄主要介紹如何使用…

深入理解Kubernetes核心:標簽與標簽選擇器實戰解析

在管理 Kubernetes 集群時&#xff0c;隨著 Pods、Services 等資源數量的增長&#xff0c;如何有效地組織和篩選它們&#xff0c;成為了一個核心問題。Kubernetes 為此提供了一個簡單卻極其強大的機制&#xff1a;標簽&#xff08;Labels&#xff09;和標簽選擇器&#xff08;L…

哈希和字符串哈希

哈希&#xff08;Hash&#xff09; Hash 表 Hash 表又稱為散列表&#xff0c;一般由 Hash 函數&#xff08;散列函數&#xff09;與鏈表結構共同實現。與離散化思想類似&#xff0c;當我們要對若干復雜信息進行統計時&#xff0c;可以用 Hash 函數把這些復雜信息映射到一個容…

【Docker基礎】Docker-Compose核心配置文件深度解析:從YAML語法到高級配置

目錄 前言 1 YAML基礎語法解析 1.1 YAML格式簡介 1.2 Docker-compose中的YAML語法規則 1.3 YAML數據類型在Compose中的應用 2 docker-compose.yml文件結構剖析 2.1 基本文件結構 2.2 版本聲明詳解 3 services配置深度解析 3.1 服務定義基礎 3.2 鏡像與構建配置 3.3…

如何判斷是否應該為了一個小功能而引入一個大體積的庫

在軟件開發中&#xff0c;判斷是否應該為了一個看似微小的功能&#xff0c;而引入一個大體積的第三方庫&#xff0c;是一項極其重要的、需要進行審慎的“投入產出比”分析的技術決策。這個決策&#xff0c;絕不能&#xff0c;僅僅基于“實現功能的便利性”&#xff0c;而必須&a…

相機定屏問題分析五:【跳幀異常】照片模式1x以上的焦段拍照之后定屏

【關注我&#xff0c;后續持續新增專題博文&#xff0c;謝謝&#xff01;&#xff01;&#xff01;】 上一篇我們講了&#xff1a; 這一篇我們開始講&#xff1a; 相機定屏問題分析五&#xff1a;【跳幀異常】照片模式1x以上的焦段拍照之后定屏9573412 目錄 一、問題背景 二…

Non-stationary Diffusion For Probabilistic Time Series Forecasting論文閱讀筆記

Non-stationary Diffusion For Probabilistic Time Series Forecasting 摘要 時間序列數據受到潛在的物理動力學和外部影響&#xff0c;其不確定性通常隨時間而變化。現有的去噪擴散概率模型&#xff08;DDPMs&#xff09;受到加性噪聲模型&#xff08;ANM&#xff09;的恒定方…

解決Docker 無法連接到官方鏡像倉庫

這個錯誤&#xff1a; Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)表示 Docker 無法連接到官方鏡像倉庫 registry-1.docker…

解決RAGFlow啟動時Elasticsearch容器權限錯誤的技術指南

文章目錄 問題現象 根本原因分析 解決方案步驟 1. 定位宿主機數據目錄 2. 修復目錄權限 3. 驗證權限狀態 4. 重啟服務 5. 檢查啟動狀態 永久解決方案:優化Docker Compose配置 高級故障排除 技術原理 問題現象 在啟動RAGFlow項目時,執行 docker logs ragflow-es-01 發現Elast…

【C++高階六】哈希與哈希表

【C高階六】哈希與哈希表1.什么是哈希&#xff1f;2.unordered系列容器3.哈希表3.1將key與存儲位置建立映射關系3.1.1直接定址法3.1.2除留余數法&#xff08;產生哈希沖突&#xff09;3.2解決哈希沖突的方法3.2.1閉散列&#xff08;開放定址法&#xff09;3.3.2開散列&#xff…

Vue 3 +Ant Design Vue 父容器樣式不影響子級,隔離

公共樣式文件 common.scss.zz-ant-status-bar {div {font-size: 12px;padding: 0 8px;} }頁面代碼<div class"zz-ant-status-bar"><a-row><a-col :span"6" ><a-progress :percent"progress.percent" size"small"…

k8s 簡介及部署方法以及各方面應用

Kubernetes 簡介及部署方法Kubernetes&#xff08;簡稱 K8s&#xff09;是一個開源的容器編排平臺&#xff0c;用于自動化容器化應用的部署、擴展、管理和運維。它由 Google 基于內部的 Borg 系統經驗開發&#xff0c;2014 年開源后由云原生計算基金會&#xff08;CNCF&#xf…