Spring Boot项目中Sentry JDBC集成与P6Spy连接URL方式的问题
问题分析与解决方案
问题原因
生成的查询语句中出现com.p6spy.engine.wrapper.PreparedStatementWrapper@7b30fd4a,本质是因为传入createPagination方法的QUERY参数并非真实的SQL字符串,而是P6Spy包装后的PreparedStatement对象调用toString()的结果——P6Spy的JDBC包装类默认toString()会输出类名+哈希值,直接拼接到SQL中导致PostgreSQL解析报错。
同时你的代码中正则表达式存在转义错误,会导致LIMIT/OFFSET子句无法被正确移除。
解决方案
1. 修正方法调用参数
确保调用createPagination时,传入的第二个参数是原始SQL字符串,而非PreparedStatement对象:
// 错误示例:传入PreparedStatement对象 PreparedStatement ps = conn.prepareStatement("SELECT * FROM users LIMIT 10 OFFSET 0"); createPagination(conn, ps, 1, 10); // 正确示例:传入原始SQL字符串 String originalSql = "SELECT * FROM users LIMIT 10 OFFSET 0"; PreparedStatement ps = conn.prepareStatement(originalSql); createPagination(conn, originalSql, 1, 10);
2. 修复正则表达式转义
Java字符串中的正则元字符需要双重转义,将PATTERN_TO_REMOVE修正为:
private static final String PATTERN_TO_REMOVE = "LIMIT\\s+\\d+\\s+OFFSET\\s+\\d+";
3. 从PreparedStatement提取SQL的正确方式
如果业务必须从PreparedStatement中获取SQL,不要直接调用toString(),需先unwrap得到真实的PostgreSQL语句对象再提取:
// 假设p6SpyPs是P6Spy包装后的PreparedStatement PreparedStatement realPs = p6SpyPs.unwrap(PreparedStatement.class); // PostgreSQL专属API获取原始SQL String sql = ((org.postgresql.PGStatement) realPs).getOriginalSql();
内容的提问来源于stack exchange,提问作者Akil Vohra
相关产品推荐
相关产品推荐

