解决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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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% 设置透…