解決MybatisPlus使用Druid1.2.11連接池查詢PG數據庫報Merge sql error的一種辦法

目錄

前言

一、問題重現

1、環境說明

2、重現步驟

3、錯誤信息

二、關于LATERAL

1、Lateral作用場景

2、在四至場景中使用

三、問題解決之道

1、源碼追蹤

2、關閉sql合并

3、改寫處理SQL

四、總結


前言

????????在博客:【寫在創作紀念日】基于SpringBoot和PostGIS的各省東西南北四至極點區縣可視化中,我們詳細而具體的講解了如何在SpringBoot中與PostGIS進行交互,實現省域的四至(東西南北)各區縣的空間檢索及可視化。后臺計算程序運行友好,功能也都還算正常,在地圖界面上點擊具體的省份、行政區劃等可以正常的查詢出東南西北四至點及所在的區縣信息,功能正常。

????????前臺看起來一切正常,但是在我們的后臺輸出日志當中,依然發現了一些不正常本地log日志。如下圖所示:

????????雖然報錯的信息對程序的功能并沒有實質的影響。但依然值得我們關注,一定是有地方執行有問題。本文即作為排查和解決報錯信息的教程,逐步來排查這個錯誤。通過對問題的重現,讓大家了解出現相關問題的場景,重現步驟等信息,為大家在實際項目中解決問題提供相關背景參考。接著講解在空間分析中Lateral關鍵字的作用,以及在省域四至問題求解中的具體使用,最后來講解如何在Mybatis-Plus中集成Druid時修復異常的信息,通過講解兩種解決辦法,讓大家了解如果在工項目中真實遇到了,可以有哪些解決辦法。

一、問題重現

????????本節將講解問題的出現場景,同時詳細列出本博客參考時使用的相關依賴的版本,也許新的依賴包已經將這些問題統統都解決。

1、環境說明

序號依賴組件版本說明
1JDK1.8JDK依賴
2Mybatis-Plus3.5.2ORM操作
3druid1.2.11數據庫連接池

2、重現步驟

????????在省域的四至所屬區縣分析中,在頁面的右側邊欄中,有全國的所有省份列表,通過點擊省份列表操作欄中的“定位”按鈕,可以實現對當前省份的四至所屬區縣求解。功能操作示意圖如下所示:

3、錯誤信息

????????這里將更多的后臺運行錯誤貼出來,看大家在實際的項目中是否也曾經遇到類似的問題。錯誤信息如下所示:

22:32:31.176 [http-nio-8080-exec-94] ERROR c.a.d.f.s.StatFilter - [mergeSql,150] - merge sql error, dbType postgresql, druid-1.2.11, sql : WITH temp_area AS ( xxx) SELECT direction,id,province_code,province_name,city_code,city_name,area_code,  area_name,type, st_asgeojson(geom) geomJson, x lon,y lat FROM bounds_info
com.alibaba.druid.sql.parser.ParserException: syntax error, error in :'T,LATERAL ST_DumpPoints ( T.geom ) AS dp', expect ), actual (, pos 208, line 1, column 208, token (at com.alibaba.druid.sql.parser.SQLParser.printError(SQLParser.java:838)at com.alibaba.druid.sql.parser.SQLParser.accept(SQLParser.java:846)at com.alibaba.druid.sql.dialect.postgresql.parser.PGSelectParser.query(PGSelectParser.java:62)at com.alibaba.druid.sql.parser.SQLSelectParser.select(SQLSelectParser.java:61)at com.alibaba.druid.sql.parser.SQLStatementParser.parseWithQuery(SQLStatementParser.java:5458)at com.alibaba.druid.sql.dialect.postgresql.parser.PGSQLStatementParser.parseWith(PGSQLStatementParser.java:421)at com.alibaba.druid.sql.parser.SQLStatementParser.parseStatementList(SQLStatementParser.java:186)at com.alibaba.druid.sql.parser.SQLStatementParser.parseStatementList(SQLStatementParser.java:101)at com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils.parameterize(ParameterizedOutputVisitorUtils.java:163)at com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils.parameterize(ParameterizedOutputVisitorUtils.java:134)at com.alibaba.druid.filter.stat.StatFilter.mergeSql(StatFilter.java:148)at com.alibaba.druid.filter.stat.StatFilter.createSqlStat(StatFilter.java:672)at com.alibaba.druid.filter.stat.StatFilter.statementPrepareAfter(StatFilter.java:325)at com.alibaba.druid.filter.FilterEventAdapter.connection_prepareStatement(FilterEventAdapter.java:118)

????????可以很明顯的看到,報錯的信息是在一個統計的過濾器中所拋出來的,過濾器所在類是:com.alibaba.druid.filter.stat.StatFilter。本小節內容到此結束,對問題的暴露介紹到這里。下面將逐步來說明這些問題。

二、關于LATERAL

????????本節將介紹一下載PostGIS空間數據庫中的Lateral關鍵字,主要將介紹Lateral關鍵字的作用場景以及在省域四至所屬區縣的問題求解過程中的作用。

1、Lateral作用場景

????????在 PostgreSQL 中,LATERAL 關鍵字用于指定一個子查詢,該子查詢可以引用出現在 FROM 子句中前面的表。它允許子查詢訪問外部查詢中的列,這在需要根據外部查詢的行動態生成結果時非常有用。

主要作用

  1. 關聯子查詢LATERAL 子查詢可以引用 FROM 子句中前面的表中的列。這使得子查詢可以根據外部查詢的行動態生成結果。

  2. 提高查詢靈活性LATERAL 允許在 FROM 子句中使用動態的子查詢,使得查詢更加靈活,可以處理更復雜的數據關系。

  3. 優化性能:在某些情況下,使用 LATERAL 可以減少重復的計算,提高查詢效率。

典型應用場景

  1. 與表值函數結合使用LATERAL 常用于與表值函數(如 unnestgenerate_series 等)結合,以便根據外部查詢的行生成動態的結果。

  2. 幾何函數:在 PostGIS 中,LATERAL 常用于與幾何函數(如 ST_DumpPoints)結合,將幾何對象分解為點集合。

  3. 多對多關系:在處理多對多關系時,LATERAL 可以動態生成中間表數據。

2、在四至場景中使用

????????先來看一下在省域四至所屬區縣的求解場景中的具體SQL實現:

WITH temp_area AS ( SELECT * FROM biz_area T WHERE T.province_code = '510000' ),
bounds_info AS (( SELECT '最東' AS direction,T.*,ST_X ( dp.geom ) AS x,ST_Y ( dp.geom ) AS y FROM temp_area T,LATERAL ST_DumpPoints ( T.geom ) AS dp ORDER BY x DESC LIMIT 1 
) UNION ALL
( SELECT '最西' AS direction,T.*,ST_X ( dp.geom ) AS x,ST_Y ( dp.geom ) AS y 
FROM temp_area T,LATERAL ST_DumpPoints ( T.geom ) AS dp ORDER BY x ASC LIMIT 1 
) UNION ALL
( SELECT '最南' AS direction,T.*,ST_X ( dp.geom ) AS x,ST_Y ( dp.geom ) AS y 
FROM temp_area T, LATERAL ST_DumpPoints ( T.geom ) AS dp ORDER BY y ASC  LIMIT 1 
) UNION ALL
(SELECT '最北' AS direction,T.*,ST_X ( dp.geom ) AS x,ST_Y ( dp.geom ) AS y 
FROM temp_area T, LATERAL ST_DumpPoints ( T.geom ) AS dp ORDER BY y DESC  LIMIT 1 ) ) SELECT direction,id,province_code,province_name,city_code,city_name,area_code,area_name,type, st_asgeojson(geom) geomJson, x lon,y lat FROM bounds_info;

????????在這個例子中,LATERAL 子查詢 dp 調用 ST_DumpPoints 函數,將幾何對象 T.geom 分解為點集合,并提取每個點的坐標信息。在求解具體的區縣信息時,會將曲線的Polygon數據轉變為點,才能在查詢結果中使用St_Y計算對應的經緯度值。 當然上面的這條sql完全是正常的,可以在客戶端中正常執行,完全可以在Navicat客戶端中進行調試。調試過程暫且不表,大家可以自行嘗試驗證。

三、問題解決之道

????????既然遇到了問題,雖然不會造成特別重大的影響,但是有運行強迫癥的我們還是要關注下,畢竟是Error,不是普通的程序運行日志。因此我們動手來解決一下遇到的問題。要解決問題,首先要明確出現的問題。這里主要分享兩個解決問題的辦法,從關閉SQL合并的設置到改寫處理SQL兩個方向來進行。

1、源碼追蹤

????????本著按圖索驥的原則,根據在控制臺中異常信息所在的代碼類,即:com.alibaba.druid.filter.stat.StatFilter中,異常拋出的行數是150行,所處理的程序邏輯如下:

????????源代碼如下所示:

public String mergeSql(String sql, DbType dbType) {if (!mergeSql) {return sql;}try {sql = ParameterizedOutputVisitorUtils.parameterize(sql, dbType, null, null, null);} catch (Exception e) {LOG.error("merge sql error, dbType " + dbType + ", druid-" + VERSION.getVersionNumber() + ", sql : " + sql, e);}return sql;
}

?????????從代碼上看,代碼不是很復雜,首先判斷要執行的SQL是否需要合并,如果不需要合并,直接返回執行SQL,否則對sql進行合并處理。當然,為了不影響后續的執行,如果轉換有問題,也對合并前的SQL原樣返回。而對于更復雜的處理,大家可以看下druid的處理方式,這里截個圖做個示例,還有一些沒截圖完整的,需要大家去了解。

2、關閉sql合并

????????了解了Druid的程序合并邏輯之后,就可以對陣下藥了。在前面的源碼追蹤內容中有介紹,如果當前的Druid應用程序設置了不需要合并sql,sql將直接原樣返回,不會做任何的處理。因此,如果不想在程序運行過程中發生異常,可以將合并SQL的開關關閉,這樣也能解決問題。在Druid中關閉sql合并的方法簡單,在Druid聲明數據庫連接池的地方關閉選項即可,代碼如下:

????????在這個配置文件中,把merge-sql:true的配置修改一下,改成false后再重新運行程序,同樣來點擊各省份,會發現在控制臺中已經沒有了合并sql的錯誤信息。控制臺窗口如下所示:

3、改寫處理SQL

????????在上面的例子中,我們選擇了關閉sql合并的設置,雖然能將問題暫時解決掉,但是對于其它需要合并的SQL就無法進行合并處理了。難道問題就無法解決了嗎?當然不是,這里我們將分享第二種方法,通過改寫處理SQL的方式來解決不關閉sql合并的問題。回到我們的查詢SQL中,可以發現,在我們的查詢需求中,我們需要求解的四至點位,其實最后都會變成一個點,即Limit 1。因此其實可以不使用Lateral的關鍵字,直接進行查詢,通過對查詢結果集排序后選擇第一條,依然是滿足我們的實際需求的,首先將查詢SQL做如下改寫,其它內容不變:

static final String FIND_ESWNAREA_BYPROVINCE_SQL = "<script>"
+ " WITH temp_area AS ( SELECT * FROM biz_area T WHERE T.province_code = #{province_code} ), "
+ " bounds_info AS ("
+ " ( SELECT '最東' AS direction,T.*,ST_X ( dp.geom ) AS x,ST_Y ( dp.geom ) AS y "
+ " FROM temp_area T,ST_DumpPoints ( T.geom ) AS dp ORDER BY x DESC LIMIT 1 "
+ " ) UNION  "
+ " ( SELECT '最西' AS direction,T.*,ST_X ( dp.geom ) AS x,ST_Y ( dp.geom ) AS y "
+ " FROM temp_area T,ST_DumpPoints ( T.geom ) AS dp ORDER BY x ASC LIMIT 1 "
+ " ) UNION "
+ " ( SELECT '最南' AS direction,T.*,ST_X ( dp.geom ) AS x,ST_Y ( dp.geom ) AS y "
+ " FROM temp_area T,ST_DumpPoints ( T.geom ) AS dp ORDER BY y ASC  LIMIT 1 "
+ " ) UNION  "
+ " (SELECT '最北' AS direction,T.*,ST_X ( dp.geom ) AS x,ST_Y ( dp.geom ) AS y "
+ " FROM temp_area T,ST_DumpPoints ( T.geom ) AS dp ORDER BY y DESC  LIMIT 1 ) "
+ " ) SELECT direction,id,province_code,province_name,city_code,city_name,area_code, "
+ " area_name,type, st_asgeojson(geom) geomJson, x lon,y lat FROM bounds_info "
+ "</script>";

????????將應用程序啟動后,再次點擊相關按鈕,程序控制成功無任何異常,如下所示:

????????頁面正常,且控制臺無任何異常輸出,成功解決以上問題。?

四、總結

????????以上就是本文的主要內容,本文即作為排查和解決報錯信息的教程,逐步來排查這個錯誤。通過對問題的重現,讓大家了解出現相關問題的場景,重現步驟等信息,為大家在實際項目中解決問題提供相關背景參考。接著講解在空間分析中Lateral關鍵字的作用,以及在省域四至問題求解中的具體使用,最后來講解如何在Mybatis-Plus中集成Druid時修復異常的信息,通過講解兩種解決辦法,讓大家了解如果在工項目中真實遇到了,可以有哪些解決辦法。

? ? ? ? 當然在實際的項目當中,選用哪種解決辦法,需要大家根據實際的需求來決定。需要大家知曉的是:當 mergeSql 設置為 true 時,Druid 會將相同的 SQL 語句進行合并,以減少統計信息的數量,這在性能統計和內存占用方面可能有所幫助,但可能會影響調試和統計信息的準確性。如果需要對某個特定的方法或場景禁用 SQL 合并處理,可以在該方法的調用環境中動態調整 Druid 的配置,或者通過其他方式(如使用不同的數據源)來實現。行文倉促,定有不足之處,歡迎各位朋友在評論區批評指正,不勝感激。

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

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

相關文章

嵌入式學習--江協51單片機day8

這個本來應該周末寫的&#xff0c;可是一直想偷懶&#xff0c;只能是拖到周一了&#xff0c;今天把51結個尾&#xff0c;明天開始學32了。 學習內容LCD1602&#xff0c;直流電機&#xff0c;AD/DA&#xff0c;紅外遙控 LCD1602 內部的框架結構 屏幕小于數據顯示區&#xff…

HUAWEI華為MateBook D 14 2021款i5,i7集顯非觸屏(NBD-WXX9,NbD-WFH9)原裝出廠Win10系統

適用型號&#xff1a;NbD-WFH9、NbD-WFE9A、NbD-WDH9B、NbD-WFE9、 鏈接&#xff1a;https://pan.baidu.com/s/1qTCbaQQa8xqLR-4Ooe3ytg?pwdvr7t 提取碼&#xff1a;vr7t 華為原廠WIN系統自帶所有驅動、出廠主題壁紙、系統屬性聯機支持標志、系統屬性專屬LOGO標志、Office…

【Python】Python 裝飾器的用法總結

在 Python 中&#xff0c;裝飾器&#xff08;Decorator&#xff09; 是一種設計模式&#xff0c;用于在不修改函數或類代碼的情況下動態地擴展其功能。裝飾器廣泛應用于日志記錄、性能監控、權限驗證等場景&#xff0c;提供了一種簡潔優雅的方式來“包裹”現有的代碼。本文將介…

【C++】控制臺小游戲

移動&#xff1a;W向上&#xff0c;S上下&#xff0c;A向左&#xff0c;D向右 程序代碼&#xff1a; #include <iostream> #include <conio.h> #include <windows.h> using namespace std;bool gameOver; const int width 20; const int height 17; int …

「MATLAB」計算校驗和 Checksum

什么是校驗和 是一個算法&#xff0c;將一串數據累加&#xff0c;得到一個和。 MATLAB程序 function c_use Checksum(packet) %Checksum 求校驗和 % 此處checksum提供詳細說明checksum 0;for i 1:length(packet)value hex2dec(packet(i));checksum checksum value; …

JavaScript面試題之消息隊列

JavaScript消息隊列詳解&#xff1a;單線程的異步魔法核心 在JavaScript的單線程世界中&#xff0c;消息隊列&#xff08;Message Queue&#xff09;是實現異步編程的核心機制&#xff0c;它像一位高效的調度員&#xff0c;讓代碼既能“一心多用”又避免卡頓。本文將深入剖析消…

京東外賣分潤系統部署實操!0門檻入駐+全平臺接入+自定義比例...這些人,賺翻了!

隨著京東外賣的發展勢頭日漸迅猛&#xff0c;許多創業者們的態度也逐漸從原本的觀望轉變為了切實的行動&#xff0c;并開始通過各個渠道詢問起了京東外賣自動分潤系統部署相關的各項事宜&#xff0c;連帶著以京東外賣自動分潤系統質量哪家強為代表的多個問題&#xff0c;也成為…

【辦公類-18-06】20250523(Python)“口腔檢查涂氟信息”批量生成打印(學號、姓名、學校、班級、身份證、戶籍、性別、民族)

背景需求: 6月是常規體檢,前幾天發了體檢表(驗血單),用Python做了姓名等信息的批量打印 【辦公類-18-04】20250520(Python)“驗血單信息”批量生成打印(學校、班級、姓名、性別)-CSDN博客文章瀏覽閱讀969次,點贊19次,收藏11次。【辦公類-18-04】20250520(Python)…

Python郵件處理:POP與SMTP

poplib簡介 poplib 是Python 3中的官方郵件庫&#xff0c;實現了POP的標準&#xff1a;RFC1939&#xff0c;用于郵件的收取。與之類似的還有imaplib 。 &#xff08;注&#xff1a;本文僅拿pop舉例&#xff09; poplib的使用方法&#xff0c;就是幾步&#xff1a; 先創建一…

IP風險度自檢,多維度守護網絡安全

如今IP地址不再只是網絡連接的標識符&#xff0c;更成為評估安全風險的核心維度。IP風險度通過多維度數據建模&#xff0c;量化IP地址在網絡環境中的安全威脅等級&#xff0c;已成為企業反欺詐、內容合規、入侵檢測的關鍵工具。據Gartner報告顯示&#xff0c;2025年全球78%的企…

Flink集成資源管理器

Flink集成資源管理器 Apache Flink 支持多種資源管理器&#xff0c;主要包括以下幾種?&#xff1a; YARN ResourceManager ?&#xff1a;適用于使用 Hadoop YARN 作為資源管理器的環境。YARN ResourceManager 負責管理集群中的資源&#xff0c;包括 CPU、內存等&#xff0c;并…

upload 文件上傳審計

目錄 LOW Medium HIgh Impossible 概述 很多Web站點都有文件上傳的接口&#xff08;比如注冊時上傳頭像等&#xff09;&#xff0c;由于沒有對上傳的文件類型進行嚴格限制&#xff0c;導致可以上傳一些文件&#xff08;比如Webshell&#xff09;。 上傳和SQL、XSS等都是主流…

【freertos-kernel】list

freertos list 基本類型結構體ListItem_t &#xff08;list.h&#xff09;List_t &#xff08;list.h&#xff09; 宏函數函數vListInitialisevListInitialiseItemvListInsertEndvListInsertuxListRemove 基本類型 freertos為了兼容性&#xff0c;重新定義了基本類型&#xff…

游戲盾的功有哪些?

游戲盾的功能主要包括以下幾方面&#xff1a; 一、網絡攻擊防護 DDoS攻擊防護&#xff1a; T級防御能力&#xff1a;游戲盾提供分布式云節點防御集群&#xff0c;可跨地區、跨機房動態擴展防御能力和負載容量&#xff0c;輕松達到T級別防御&#xff0c;有效抵御SYN Flood、UD…

PycharmFlask 學習心得:路由(3-4)

對路由的理解&#xff1a; 用戶輸入網址 例如&#xff1a;http://localhost:5000/hello 瀏覽器會向這個地址發起一個 HTTP 請求&#xff08;比如 GET 請求&#xff09; 請求到達 Flask 的服務器 Flask 監聽著某個端口&#xff08;如 5000&#xff09;&#xff0c;收到請求后…

課程與考核

6.1 課程講解與實戰考核 6.1.1 SQL注入篇考核 考核目標&#xff1a;通過手動注入與工具結合&#xff0c;獲取目標數據庫敏感信息。 題目示例&#xff1a; 目標URL&#xff1a;http://vuln-site.com/product?id1 要求&#xff1a; 判斷注入類型&#xff08;聯合查詢/報錯注…

線程池介紹,分類,實現(工作原理,核心組成,拒絕策略),固態線程池的實現+詳細解釋(支持超時取消機制和不同的拒絕策略)

目錄 線程池 介紹 分類 實現 工作原理 核心組成 拒絕策略 固態線程池 功能 std::future 實現 拒絕策略支持 提交任務 超時取消 用戶檢測取消 安全銷毀 代碼 測試 線程池 介紹 線程池(圖解,本質,模擬實現代碼),添加單例模式(懶漢思路代碼)_線程池單例-CSDN博…

紡線機與PLC通訊故障?ETHERCAT/CANopen網關秒解協議難題

在紡織行業智能化轉型浪潮中&#xff0c;設備間高效通信是實現自動化生產的關鍵。JH-ECT009疆鴻智能EtherCAT轉CANopen協議轉換網關&#xff0c;憑借出色的協議適配能力&#xff0c;成功架起倍福PLC與自動紡線機間的通信橋梁&#xff0c;為紡織廠自動化生產注入強勁動力。 紡織…

深度剖析并發I/O模型select、poll、epoll與IOCP核心機制

核心概要&#xff1a;select、poll、epoll 和 IOCP 是四種用于提升服務器并發處理能力的I/O模型或機制。前三者主要屬于I/O多路復用范疇&#xff0c;允許單個進程或線程監視多個I/O流的狀態&#xff1b;而 IOCP 則是一種更為徹底的異步I/O模型。 一、引言&#xff1a;為何需要這…

microsoft中word如何添加個人簽名

https://support.microsoft.com/zh-cn/office/%E6%8F%92%E5%85%A5%E7%AD%BE%E5%90%8D-f3b3f74c-2355-4d53-be89-ae9c50022730 插入簽名圖片 圖片格式選擇裁剪合適的大小 使用的簽名如果不是白色紙張的話可以重新著色 依次點擊圖片格式——顏色——重新著色——黑白50% 設置透…