解决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、环境说明
序号 | 依赖组件 | 版本 | 说明 |
1 | JDK | 1.8 | JDK依赖 |
2 | Mybatis-Plus | 3.5.2 | ORM操作 |
3 | druid | 1.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
子句中前面的表。它允许子查询访问外部查询中的列,这在需要根据外部查询的行动态生成结果时非常有用。
主要作用
-
关联子查询:
LATERAL
子查询可以引用FROM
子句中前面的表中的列。这使得子查询可以根据外部查询的行动态生成结果。 -
提高查询灵活性:
LATERAL
允许在FROM
子句中使用动态的子查询,使得查询更加灵活,可以处理更复杂的数据关系。 -
优化性能:在某些情况下,使用
LATERAL
可以减少重复的计算,提高查询效率。
典型应用场景
-
与表值函数结合使用:
LATERAL
常用于与表值函数(如unnest
、generate_series
等)结合,以便根据外部查询的行生成动态的结果。 -
几何函数:在 PostGIS 中,
LATERAL
常用于与几何函数(如ST_DumpPoints
)结合,将几何对象分解为点集合。 -
多对多关系:在处理多对多关系时,
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 的配置,或者通过其他方式(如使用不同的数据源)来实现。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。
相关文章:

解决MybatisPlus使用Druid1.2.11连接池查询PG数据库报Merge sql error的一种办法
目录 前言 一、问题重现 1、环境说明 2、重现步骤 3、错误信息 二、关于LATERAL 1、Lateral作用场景 2、在四至场景中使用 三、问题解决之道 1、源码追踪 2、关闭sql合并 3、改写处理SQL 四、总结 前言 在博客:【写在创作纪念日】基于SpringBoot和PostG…...
Neo4j 完全指南:从入门到精通
第1章:Neo4j简介与图数据库基础 1.1 图数据库概述 传统关系型数据库与图数据库的对比图数据库的核心优势图数据库的应用场景 1.2 Neo4j的发展历史 Neo4j的起源与演进Neo4j的版本迭代Neo4j在图数据库领域的地位 1.3 图数据库的基本概念 节点(Node)与关系(Relat…...
day51 python CBAM注意力
目录 一、CBAM 模块简介 二、CBAM 模块的实现 (一)通道注意力模块 (二)空间注意力模块 (三)CBAM 模块的组合 三、CBAM 模块的特性 四、CBAM 模块在 CNN 中的应用 一、CBAM 模块简介 在之前的探索中…...

使用VMware克隆功能快速搭建集群
自己搭建的虚拟机,后续不管是学习java还是大数据,都需要集群,java需要分布式的微服务,大数据Hadoop的计算集群,如果从头开始搭建虚拟机会比较费时费力,这里分享一下如何使用克隆功能快速搭建一个集群 先把…...

篇章一 论坛系统——前置知识
目录 1.软件开发 1.1 软件的生命周期 1.2 面向对象 1.3 CS、BS架构 1.CS架构编辑 2.BS架构 1.4 软件需求 1.需求分类 2.需求获取 1.5 需求分析 1. 工作内容 1.6 面向对象分析 1.OOA的任务 2.统一建模语言UML 3. 用例模型 3.1 用例图的元素 3.2 建立用例模型 …...
十二、【ESP32全栈开发指南: IDF开发环境下cJSON使用】
一、JSON简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,具有以下核心特性: 完全独立于编程语言的文本格式易于人阅读和编写易于机器解析和生成基于ECMAScript标准子集 1.1 JSON语法规则 {"name"…...

Qt/C++学习系列之列表使用记录
Qt/C学习系列之列表使用记录 前言列表的初始化界面初始化设置名称获取简单设置 单元格存储总结 前言 列表的使用主要基于QTableWidget控件,同步使用QTableWidgetItem进行单元格的设置,最后可以使用QAxObject进行单元格的数据读出将数据进行存储。接下来…...
【Pandas】pandas DataFrame dropna
Pandas2.2 DataFrame Missing data handling 方法描述DataFrame.fillna([value, method, axis, …])用于填充 DataFrame 中的缺失值(NaN)DataFrame.backfill(*[, axis, inplace, …])用于**使用后向填充(即“下一个有效观测值”)…...

基于django+vue的健身房管理系统-vue
开发语言:Python框架:djangoPython版本:python3.8数据库:mysql 5.7数据库工具:Navicat12开发软件:PyCharm 系统展示 会员信息管理 员工信息管理 会员卡类型管理 健身项目管理 会员卡管理 摘要 健身房管理…...

Yolo11改进策略:Block改进|FCM,特征互补映射模块|AAAI 2025|即插即用
1 论文信息 FBRT-YOLO(Faster and Better for Real-Time Aerial Image Detection)是由北京理工大学团队提出的专用于航拍图像实时目标检测的创新框架,发表于AAAI 2025。论文针对航拍场景中小目标检测的核心难题展开研究,重点解决…...
【系统架构设计师-2025上半年真题】综合知识-参考答案及部分详解(回忆版)
更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 【第1题】【第2题】【第3题】【第4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19题】【第20~21题】【第…...

简单聊下阿里云DNS劫持事件
阿里云域名被DNS劫持事件 事件总结 根据ICANN规则,域名注册商(Verisign)认定aliyuncs.com域名下的部分网站被用于非法活动(如传播恶意软件);顶级域名DNS服务器将aliyuncs.com域名的DNS记录统一解析到shado…...
LTR-381RGB-01RGB+环境光检测应用场景及客户类型主要有哪些?
RGB环境光检测 功能,在应用场景及客户类型: 1. 可应用的儿童玩具类型 (1) 智能互动玩具 功能:通过检测环境光或物体颜色触发互动(如颜色识别积木、光感音乐盒)。 客户参考: LEGO(乐高&#x…...

循环语句之while
While语句包括一个循环条件和一段代码块,只要条件为真,就不断 循环执行代码块。 1 2 3 while (条件) { 语句 ; } var i 0; while (i < 100) {console.log(i 当前为: i); i i 1; } 下面的例子是一个无限循环,因…...

机器学习复习3--模型评估
误差与过拟合 我们将学习器对样本的实际预测结果与样本的真实值之间的差异称为:误差(error)。 误差定义: ①在训练集上的误差称为训练误差(training error)或经验误差(empirical error&#x…...

联邦学习带宽资源分配
带宽资源分配是指在网络中如何合理分配有限的带宽资源,以满足各个通信任务和用户的需求,尤其是在多用户共享带宽的情况下,如何确保各个设备或用户的通信需求得到高效且公平的满足。带宽是网络中的一个重要资源,通常指的是单位时间…...

今日行情明日机会——20250609
上证指数放量上涨,接近3400点,个股涨多跌少。 深证放量上涨,但有个小上影线,相对上证走势更弱。 2025年6月9日涨停股主要行业方向分析(基于最新图片数据) 1. 医药(11家涨停) 代表标…...

GC1808:高性能音频ADC的卓越之选
在音频处理领域,高质量的音频模数转换器(ADC)是实现精准音频数字化的关键。GC1808,一款96kHz、24bit立体声音频ADC,以其卓越的性能和高性价比脱颖而出,成为众多音频设备制造商的理想选择。 GC1808集成了64倍…...

生产管理系统开发:专业软件开发公司的实践与思考
生产管理系统开发的关键点 在当前制造业智能化升级的转型背景下,生产管理系统开发正逐步成为企业优化生产流程的重要技术手段。不同行业、不同规模的企业在推进生产管理数字化转型过程中,面临的挑战存在显著差异。本文结合具体实践案例,分析…...

VASP软件在第一性原理计算中的应用-测试GO
VASP软件在第一性原理计算中的应用 VASP是由维也纳大学Hafner小组开发的一款功能强大的第一性原理计算软件,广泛应用于材料科学、凝聚态物理、化学和纳米技术等领域。 VASP的核心功能与应用 1. 电子结构计算 VASP最突出的功能是进行高精度的电子结构计算ÿ…...

Centos 7 服务器部署多网站
一、准备工作 安装 Apache bash sudo yum install httpd -y sudo systemctl start httpd sudo systemctl enable httpd创建网站目录 假设部署 2 个网站,目录结构如下: bash sudo mkdir -p /var/www/site1/html sudo mkdir -p /var/www/site2/html添加测试…...

从数据报表到决策大脑:AI重构电商决策链条
在传统电商运营中,决策链条往往止步于“数据报表层”:BI工具整合历史数据,生成滞后一周甚至更久的销售分析,运营团队凭经验预判需求。当爆款突然断货、促销库存积压时,企业才惊觉标准化BI的决策时差正成为增长瓶颈。 一…...
在ubuntu等linux系统上申请https证书
使用 Certbot 自动申请 安装 Certbot Certbot 是 Let’s Encrypt 官方推荐的自动化工具,支持多种操作系统和服务器环境。 在 Ubuntu/Debian 上: sudo apt update sudo apt install certbot申请证书 纯手动方式(不自动配置)&…...

(12)-Fiddler抓包-Fiddler设置IOS手机抓包
1.简介 Fiddler不但能截获各种浏览器发出的 HTTP 请求,也可以截获各种智能手机发出的HTTP/ HTTPS 请求。 Fiddler 能捕获Android 和 Windows Phone 等设备发出的 HTTP/HTTPS 请求。同理也可以截获iOS设备发出的请求,比如 iPhone、iPad 和 MacBook 等苹…...
【R语言编程——数据调用】
这里写自定义目录标题 可用库及数据集外部数据导入方法查看数据集信息 在R语言中,有多个库支持调用内置数据集或外部数据,包括studentdata等教学或示例数据集。以下是常见的库和方法: 可用库及数据集 openintro库 该库包含多个教学数据集&a…...

第2课 SiC MOSFET与 Si IGBT 静态特性对比
2.1 输出特性对比 2.2 转移特性对比 2.1 输出特性对比 器件的输出特性描述了当温度和栅源电压(栅射电压)为某一具体数值时,漏极电流(集电极电流...

MCP和Function Calling
MCP MCP(Model Context Protocol,模型上下文协议) ,2024年11月底,由 Anthropic 推出的一种开放标准,旨在统一大模型与外部数据源和工具之间的通信协议。MCP 的主要目的在于解决当前 AI 模型因数据孤岛限制而…...
软件工程教学评价
王海林老师您好。 您的《软件工程》课程成功地将宏观的理论与具体的实践相结合。上半学期的理论教学中,您通过丰富的实例,将“高内聚低耦合”、SOLID原则等抽象概念解释得十分透彻,让这些理论不再是停留在纸面的名词,而是可以指导…...

解密鸿蒙系统的隐私护城河:从权限动态管控到生物数据加密的全链路防护
摘要 本文以健康管理应用为例,展示鸿蒙系统如何通过细粒度权限控制、动态权限授予、数据隔离和加密存储四大核心机制,实现复杂场景下的用户隐私保护。我们将通过完整的权限请求流程和敏感数据处理代码,演示鸿蒙系统如何平衡功能需求与隐私安…...
前端打包工具简单介绍
前端打包工具简单介绍 一、Webpack 架构与插件机制 1. Webpack 架构核心组成 Entry(入口) 指定应用的起点文件,比如 src/index.js。 Module(模块) Webpack 把项目当作模块图,模块可以是 JS、CSS、图片等…...