JSQLParser 4.x 中 IN 表达式缺少括号的问题排查与解决
JSQLParser 4.x 中 IN 表达式缺少括号的问题排查与解决问题背景在使用 MyBatis Plus 拦截器动态拼接数据权限 SQL 时使用 JSQLParser 构造IN表达式运行后发现生成的 SQL 语法错误-- 期望SELECT*FROMsdk_projectWHEREdeleted0ANDsales_user_idIN(aaa,bbb,ccc)-- 实际SELECT*FROMsdk_projectWHEREdeleted0ANDsales_user_idINaaa,bbb,cccDruid 随即抛出异常com.alibaba.druid.sql.parser.ParserException: not supported. pos 116, line 1, column 116, token ,问题代码InExpressioninExpressionnewInExpression();inExpression.setLeftExpression(newColumn(sales_user_id));inExpression.setRightExpression(newExpressionList(ids.stream().map(StringValue::new).collect(Collectors.toList())));根因分析环境依赖版本JSQLParser4.9通过 MyBatis-Plus 3.5.7 传递引入关键结论InExpression在调用toString()时括号完全由rightExpression.toString()自身决定InExpression本身不负责添加括号。ExpressionList.toString() 不带括号通过反编译jsqlparser-4.9.jar验证// ExpressionList.toString() 等价源码OverridepublicStringtoString(){StringBuildersbnewStringBuilder();appendTo(sb);// 自行拼接不加括号returnsb.toString();// 输出aaa, bbb, ccc}ParenthesedExpressionList.toString() 带括号// ParenthesedExpressionList.toString() 等价源码OverridepublicStringtoString(){returnPlainSelect.getStringList(this,true,true);// ^^^^ ^^^^// useBracketstrue ─┘ │// useCommatrue ─────────┘// 输出(aaa, bbb, ccc)}两个true是源码内硬编码的不是外部调用者传入的。通过字节码可以直接验证ParenthesedExpressionList.toString(): 0: aload_0 ← this 1: iconst_1 ← 硬编码 trueuseBrackets 2: iconst_1 ← 硬编码 trueuseComma 3: invokestatic PlainSelect.getStringList:(List, Z, Z)三种写法实测对比ListStringidsArrays.asList(aaa,bbb,ccc);// A: Parenthesis 包裹 ExpressionListInExpressioninAnewInExpression();inA.setLeftExpression(newColumn(user_id));inA.setRightExpression(newParenthesis(newExpressionList(ids.stream().map(StringValue::new).collect(Collectors.toList()))));// 输出user_id IN (aaa, bbb, ccc) ✓// B: ParenthesedExpressionListInExpressioninBnewInExpression();inB.setLeftExpression(newColumn(user_id));inB.setRightExpression(newParenthesedExpressionList(ids.stream().map(StringValue::new).collect(Collectors.toList())));// 输出user_id IN (aaa, bbb, ccc) ✓// C: 裸 ExpressionList原始问题写法InExpressioninCnewInExpression();inC.setLeftExpression(newColumn(user_id));inC.setRightExpression(newExpressionList(ids.stream().map(StringValue::new).collect(Collectors.toList())));// 输出user_id IN aaa, bbb, ccc ✗ SQL 语法错误A 和 B 的 SQL 输出完全相同两种写法均可解决问题。Parenthesis 的原理Parenthesis是一个装饰器toString()直接硬拼括号// Parenthesis.toString() 等价源码OverridepublicStringtoString(){return(expression);}字节码验证Parenthesis.toString(): 7: ldc ( ← 硬拼左括号 13: append(expression) 31: ldc ) ← 硬拼右括号 39: areturntoString() 的触发时机setRightExpression()只存引用不触发toString()。整个序列化发生在最后调用statement.toString()时// 构造阶段只存引用无任何输出newParenthesedExpressionList(list)// 构造对象inExpression.setRightExpression(...)// 存引用// 序列化阶段statement.toString() 触发整棵 AST 递归序列化returnstatement.toString();// └─ InExpression.toString()// └─ StringBuilder.append(IN )// └─ StringBuilder.append(rightExpression) ← 此处才调用 rightExpression.toString()// └─ ParenthesedExpressionList.toString()// └─ PlainSelect.getStringList(this, true, true)// └─ 输出 (aaa, bbb, ccc)解决方案将ExpressionList替换为ParenthesedExpressionList// 修复前inExpression.setRightExpression(newExpressionList(ids.stream().map(StringValue::new).collect(Collectors.toList())));// 修复后inExpression.setRightExpression(newParenthesedExpressionList(ids.stream().map(StringValue::new).collect(Collectors.toList())));或者用Parenthesis包裹也可以两者 SQL 输出等价inExpression.setRightExpression(newParenthesis(newExpressionList(ids.stream().map(StringValue::new).collect(Collectors.toList()))));总结写法SQL 输出说明ExpressionList(...)IN a, b✗不带括号SQL 语法错误ParenthesedExpressionList(...)IN (a, b)✓内部硬编码useBracketstrueParenthesis(ExpressionList(...))IN (a, b)✓装饰器强制加括号注意此问题仅出现在 JSQLParser 4.x。若项目升级至 5.x建议重新验证 API 兼容性。

相关新闻

HarmonyOS应用开发实战:猫猫大作战-排序在下落算法中的关键作用

HarmonyOS应用开发实战:猫猫大作战-排序在下落算法中的关键作用

前言 在重力下落算法中,排序顺序至关重要——必须先处理底部的猫咪再处理顶部的,否则会出现“穿透“现象。Array.sort() 配合比较函数实现自定义排序。 本文以 GameEngine.updateCats() 中的 sort((a,b) > b.y - a.y) 为锚点,讲解排序在…

2026/7/28 2:04:27 阅读更多 →
私有化IM部署:能用只是开始,全栈信创适配等五道坎决定能否管好

私有化IM部署:能用只是开始,全栈信创适配等五道坎决定能否管好

私有化IM部署热背后:“能用”只是开始,全栈信创适配等五道坎决定能否“管好” 当越来越多的组织把即时通讯从SaaS拉回内网,私有化部署似乎成了解决数据焦虑的“标准答案”。但一个新的管理盲区正在浮现:许多团队以为只要聊天功能在…

2026/7/28 2:04:27 阅读更多 →
2026 年程序员找工作,为什么 AI 写出的代码反而成了简历的“硬伤”?

2026 年程序员找工作,为什么 AI 写出的代码反而成了简历的“硬伤”?

聊《一份看似完整的程序员就业方案,为什么投递时没效果?》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。摘要摘要:2026 年,AI 编程工具已不是新鲜事,但能…

2026/7/28 2:03:26 阅读更多 →

最新新闻

C语言中常用计时方法总结

C语言中常用计时方法总结

C语言中常用计时方法总结 1. time() 头文件:time.h 函数原型:time_t time(time_t * timer) 功能:返回以格林尼治时间(GMT)为标准,从1970年1月1日00:00:00到现在的此时此刻所经过的秒数。 用time()函数结合其…

2026/7/28 2:22:32 阅读更多 →
Mike工具源码解析:核心组件与实现原理

Mike工具源码解析:核心组件与实现原理

Mike工具源码解析:核心组件与实现原理 【免费下载链接】mike Manage multiple versions of your MkDocs-powered documentation via Git 项目地址: https://gitcode.com/gh_mirrors/mi/mike Mike是一款通过Git管理MkDocs文档多版本的强大工具,能够…

2026/7/28 2:22:32 阅读更多 →
开发者必看:ModularAvatar API深度解析与扩展开发

开发者必看:ModularAvatar API深度解析与扩展开发

开发者必看:ModularAvatar API深度解析与扩展开发 【免费下载链接】modular-avatar 项目地址: https://gitcode.com/gh_mirrors/mo/modular-avatar ModularAvatar是一款功能强大的开源工具,为VRChat avatar开发者提供了模块化的组件系统和灵活的…

2026/7/28 2:22:32 阅读更多 →
开源大模型技术对比:LLaMA、Qwen与DeepSeek

开源大模型技术对比:LLaMA、Qwen与DeepSeek

1. 开源大模型技术格局概述2023年以来的开源大模型领域呈现出爆发式增长态势,LLaMA 2/3、Qwen和DeepSeek三大系列模型凭借各自的技术特色形成了三足鼎立的局面。作为长期跟踪AI技术发展的从业者,我观察到这三个项目在模型架构、训练策略和应用场景上展现…

2026/7/28 2:22:32 阅读更多 →
基于MCP协议构建IDA Pro自动化分析服务器:原理、实现与恶意代码分析实战

基于MCP协议构建IDA Pro自动化分析服务器:原理、实现与恶意代码分析实战

1. 项目概述:为什么我们需要一个IDA Pro的MCP Server?如果你长期从事恶意代码分析或逆向工程,肯定对IDA Pro这个“神器”又爱又恨。爱的是它无与伦比的静态分析能力,恨的是那些重复、繁琐的操作——比如,为了分析一个恶…

2026/7/28 2:22:32 阅读更多 →
黄仁勋X账号2天30万粉:技术内容传播的平台策略分析

黄仁勋X账号2天30万粉:技术内容传播的平台策略分析

这次我们来看一个很有意思的现象:英伟达CEO黄仁勋的个人X账号在短短两天内粉丝数就超过了领英官方账号十年的积累。这个对比背后反映的是社交媒体平台影响力和用户关注度的重大变化。从数据来看,黄仁勋的X账号在开通后48小时内就获得了超过30万粉丝&…

2026/7/28 2:21:32 阅读更多 →

日新闻

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:43 阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑:把几百页的财报、法规、技术手册扔给向量库,问一个具体问题,搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了,要么藏在几十条结果的最下面。语义相似≠真正相关,这个…

2026/7/28 0:00:43 阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营,从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候,每天刷半小时抖音,手动把爆款视频的口播敲进备忘录,一条2分钟的视频得花十来分钟,碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:43 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/27 4:33:59 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/27 6:31:56 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/27 4:01:12 阅读更多 →

月新闻