Java 执行 Postgresql Jdbc 类型异常时,复杂sql难定位的解决方案
2023-02-26 10:18:17 时间
由于复杂sql篇幅比较长,这里就随意执行一串比较简单的sql作为代表,怎么去实现较为精准的异常sql定位,帮助各位开发小伙伴解决问题
相关驱动前置说明
<!-- postgresql jdbc 驱动包 --> <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql --> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.2.24</version> </dependency> <!-- druid jdbc连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.21</version> </dependency>
执行sql如下:
// 随意编写的一句sql String sql = "select * from cr_vehicle_type " + "where VEHICLE_TYPE_ID in(?,200) " + " and create_time > ? "; // create_time 字段故意传入时间字符串,pg会报错,mysql是不会的 EDb.use("pg").find(VehicleType.class,sql,100, "2020-01-08");
异常信息如下:
com.jfinal.plugin.activerecord.ActiveRecordException: java.lang.RuntimeException: org.postgresql.util.PSQLException: ERROR: operator does not exist: timestamp without time zone > character varying 建议:No operator matches the given name and argument types. You might need to add explicit type casts. 位置:81 at com.edbplus.db.EDbPro.find(EDbPro.java:1144)
如果是以上异常信息提示的话,我们很难去定位到 create_time 字段的类型有异,简单的sql还好,复杂的sql有好多字段,光凭 【位置:81】 和 【ERROR: operator does not exist: timestamp without time zone > character varying】 等关键字眼,对开发人员来说,实在太难了
所以建议结合druid进行相关简单的改造
继承 FilterEventAdapter 实现sql上下游动作的相关监听
public class EDbDruidSqlLogFilter extends FilterEventAdapter{ ... ... /** * druid自带的sql异常之上下游监听 -> 执行sql报错之后触发 * @param statement * @param sql * @param error */ @Override protected void statement_executeErrorAfter(StatementProxy statement, String sql, Throwable error) { try{ if(error.getMessage().contains("位置")){ String errStr = error.getMessage(); // 提取 【位置:81】 里的数字,便于结合sql语句进行精准范围定位 int idx = ReUtil.getFirstNumber(errStr.substring(errStr.indexOf("位置"))); int startIdx,endIdx =0; if((idx - 20)>0){ startIdx = idx - 20; }else{ startIdx = 0; } if((idx + 10)<sql.length()){ endIdx = idx + 10; }else{ endIdx = sql.length(); } // 弥补pgsql打印时,无法精准输出异常字段的问题 String errMsg = "sql异常位置:" + sql.substring(startIdx,endIdx) ; log.error(errMsg); } }catch (Throwable e) { log.error(e); } } }
结果如下
如上图所示,我们就可以通过 【sql异常位置: and create_time > ?】的提示并结合【ERROR: operator does not exist: timestamp without time zone > character varying】,非常方便定位到异常信息和问题,能很快的发现问题并修复该异常,节省大量的测试时间和结构性差异对比
希望有帮助到大家,在java往postgresql开发的路上快速迭代和提升~~~
欢迎大家留言
你还在原价购买阿里云、腾讯云、华为云、天翼云产品?那就亏大啦!现在申请成为四大品牌云厂商VIP用户,可以3折优惠价购买云服务器等云产品,并且可享四大云服务商产品终身VIP优惠价,还等什么?赶紧点击下面对应链接免费申请VIP客户吧:
相关文章
- 多线程并发拓展
- 紧跟Spring Boot 3 生态,Spring Cloud Tencent 发布最新匹配版本!
- 【k哥爬虫普法】程序员183并发爬取官方网站,直接获刑3年?
- 初始数组--Java版
- 类与对象--Java
- java将有父子关系的list转换为树形结构
- Java集合操作示例
- java字符串练习题8、同构字符串
- java字符串练习题2、反向输出英文字符串
- java字符串练习题3、字符串中字符是否相同判断
- java字符串练习题4、统计一行字符串中所有的字符类型数量
- java字符串练习题5、罗马数字转整数
- java字符串练习题6、最后一个单词的长度
- java字符串练习题7、验证回文串
- Java 解析 带 T Z 的 UTC 时间格式 日期
- JAVA实现代码热更新
- Java 的 Optional.ofNullable()方法,防止空指针异常
- java实现 byte数组与int ,float ,short 等类型进行相互转换
- 【Java入门】Java注释和关键字
- 如何使用IDEA查看jar包,jar包的正确打开方式