当前位置: 首页 > news >正文

Druid连接池工具公式化SQL附踩坑记录

1. 需求

使用Druid连接池工具格式化sql用于回显时候美观展示

2. 代码示例

2.1 依赖

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.6</version>
</dependency>

2.2 ParseUtils

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGOutputVisitor;
import com.alibaba.druid.sql.parser.SQLParserUtils;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;import java.util.List;/*** @author pp_lan* @date 2024/1/15*/
public class ParseUtils {private ParseUtils() {}public static String format(String sql, String dbTypeStr) {DbType dbType = DbType.of(dbTypeStr);if (dbType == null) {throw new RuntimeException("不支持的数据库类型");}List<SQLStatement> statementList = toStatementList(sql, dbType);String result = sqlToString(statementList, dbTypeStr, null);return result;}public static List<SQLStatement> toStatementList(String sql, DbType dbType) {SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType);return parser.parseStatementList();}public static String sqlToString(List<SQLStatement> statementList, String dbType, List<Object> parameters) {StringBuilder sb = new StringBuilder();SQLASTOutputVisitor visitor;switch (dbType) {case "postgresql":visitor = new PGOutputVisitor(sb);break;case "mysql":visitor = new MySqlOutputVisitor(sb);break;default:visitor = new SQLASTOutputVisitor(sb);}visitor.setParameters(parameters);for (SQLStatement statement : statementList) {statement.accept(visitor);}return sb.toString();}public static void main(String[] args) {// 使用::将数值转为varchartry {System.out.println("[使用::转换]");String sql = "select sum(in_use) :: varchar from t_user";System.out.println(format(sql, DbType.postgresql.name()));} catch (Exception e) {System.out.println("使用::转换异常");}// 使用cast将数值转为varchartry {System.out.println("[使用cast转换]");String newSql = "select cast(sum(in_use) as varchar) from t_user";System.out.println(format(newSql, DbType.postgresql.name()));} catch (Exception e) {System.out.println("使用cast转换异常");}}}

3. 运行结果

[使用::转换]
SELECT sum(in_use)::varchar
FROM t_user
[使用cast转换]
SELECT CAST(sum(in_use) AS varchar)
FROM t_user

4. 踩坑记录

4.1 描述

之前我使用的是druid为1.2.4版本,在解析pg库sql时候,发现执行结果如下:

[使用::转换]
使用::转换异常
[使用cast转换]
SELECT CAST(sum(in_use) AS varchar)
FROM t_user

可以发现,转换函数::在解析时候异常了

4.2 解决方法

切换高版本1.2.6及以上,可以正常解析。

4.3 总结

druid的1.2.6以下版本对于包含数值使用::转换为varchar的场景不支持,会导致解析报错。可以使用以下方法解决:

  • 升级druid版本到1.2.6及以上
  • 在格式化的方法上加上try-catch,格式化异常的时候使用原来的sql用于回显
http://www.lryc.cn/news/281117.html

相关文章:

  • Linux内核--网络协议栈(二)UDP数据包发送
  • 基于深度学习的时间序列算法总结
  • nginx中多个server块共用upstream会相互影响吗
  • 基于信号完整性的一些PCB设计建议
  • 《BackTrader量化交易图解》第8章:plot 绘制金融图
  • 什么是欧拉筛??
  • 2023年全国职业院校技能大赛软件测试赛题—单元测试卷⑩
  • 使用WAF防御网络上的隐蔽威胁之SSRF攻击
  • Redis基础系列-哨兵模式
  • 【angular教程240112】09(完) Angular中的数据请求 与 路由
  • go中拷贝文件操作
  • 未来气膜体育馆的发展趋势是什么?
  • 通信扫盲(五)
  • nbcio-boot项目的文件上传与回显处理方法
  • 《动手学深度学习》学习笔记 第9章 现代循环神经网络
  • 「HDLBits题解」Vector100r
  • 如何制作专业商业画册,提升品牌形象
  • vim升级和配置
  • java通过okhttp方式实现https请求的工具类(绕过证书验证)
  • mysql定时备份shell脚本和还原
  • DevOps搭建(十六)-Jenkins+K8s部署详细步骤
  • WaitForSingleObject 函数的诸多用途与使用场景总结
  • 4、Redis高并发分布式锁实战
  • matlab subs 函数计算太慢
  • 如何确保网络传输的安全性和稳定性?
  • 鸿蒙应用开发学习:改进小鱼动画实现按键一直按下时控制小鱼移动和限制小鱼移出屏幕
  • 紫光展锐5G扬帆出海 | Blade系列勇当拉美5G先锋
  • 如何设计一个高并发系统?
  • 基于WebRTC技术的EasyRTC视频云服务系统在线视频客服解决方案
  • 黑马程序员——2022版软件测试——乞丐版——day04