利用JDBC的PrepareStatement打印真实SQL的方法详解


当前第2页 返回上一页

printRealSql 函数源码如下:

/** 
 * 在开发过程,SQL语句有可能写错,如果能把运行时出错的 SQL 语句直接打印出来,那对排错非常方便,因为其可以直接拷贝到数据库客户端进行调试。 
 * 
 * @param sql 
 *   SQL 语句,可以带有 ? 的占位符 
 * @param params 
 *   插入到 SQL 中的参数,可单个可多个可不填 
 * @return 实际 sql 语句 
 */ 
public static String printRealSql(String sql, Object[] params) { 
 if(params == null || params.length == 0) { 
  LOGGER.info("The SQL is------------>\n" + sql); 
  return sql; 
 } 
  
 if (!match(sql, params)) { 
  LOGGER.info("SQL 语句中的占位符与参数个数不匹配。SQL:" + sql); 
  return null; 
 } 
 
 int cols = params.length; 
 Object[] values = new Object[cols]; 
 System.arraycopy(params, 0, values, 0, cols); 
 
 for (int i = 0; i < cols; i++) { 
  Object value = values[i]; 
  if (value instanceof Date) { 
   values[i] = "'" + value + "'"; 
  } else if (value instanceof String) { 
   values[i] = "'" + value + "'"; 
  } else if (value instanceof Boolean) { 
   values[i] = (Boolean) value ? 1 : 0; 
  } 
 } 
  
 String statement = String.format(sql.replaceAll("\\?", "%s"), values); 
 
 LOGGER.info("The SQL is------------>\n" + statement); 
 
 ConnectionMgr.addSql(statement); // 用来保存日志 
  
 return statement; 
} 
 
/** 
 * ? 和参数的实际个数是否匹配 
 * 
 * @param sql 
 *   SQL 语句,可以带有 ? 的占位符 
 * @param params 
 *   插入到 SQL 中的参数,可单个可多个可不填 
 * @return true 表示为 ? 和参数的实际个数匹配 
 */ 
private static boolean match(String sql, Object[] params) { 
 if(params == null || params.length == 0) return true; // 没有参数,完整输出 
  
 Matcher m = Pattern.compile("(\\?)").matcher(sql); 
 int count = 0; 
 while (m.find()) { 
  count++; 
 } 
  
 return count == params.length; 
} 

可见,上述思路是非常简单的,——有多少个 ? 占位符,就要求有多少个参数,然后一一对照填入(数组)。match 函数会检查第一个步骤,检查个数是否匹配,否则会返回“SQL 语句中的占位符与参数个数不匹配”的提示;然后,参数的值会被转换为符合 SQL 值所要求的类型;最后,就是将 SQL 一一填入,——此处使用了一个字符串的技巧,先把 ? 字符通通转换为 %s,——那是 String.format 可识别的占位符,如此再传入 Object[] 参数列表,即可得出我们期待的 SQL 结果。

我们不能保证那 SQL 可以直接放到数据库中被解析。因为我们的初衷只是把 SQL 打印出来,务求更近一步让程序员在开发阶段看到 SQL 是怎么样子的,而且不是一堆 ?、?……,这样会显得更符合真实情形一点。

PrepareStatement 内部源码肯定有这一步骤或者某个变量是表示那个真实 SQL 的,——只是没有暴露出来。如果有,那么对程序员会更友好一些。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。


标签:SQL

返回前面的内容

相关阅读 >>

oledb和odbc的区别(优缺点)

sql server数据库错误5123解决方案

sql怎么修改表内容

sql中如何实现日期自动补全

oblog_4.6_sql 语句

合并sql脚本文件的方法分享

sqlserver 手工实现差异备份的步骤

一文带你理解慢sql分析与优化

asp.net下oracle,sql server,access万能数据库通用类

sql语句如何优化?

更多相关阅读请进入《sql》频道 >>


数据库系统概念 第6版
书籍

数据库系统概念 第6版

机械工业出版社

本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...