亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何獲取PreparedStatement的SQL?

如何獲取PreparedStatement的SQL?

收到一只叮咚 2019-07-26 17:03:33
如何獲取PreparedStatement的SQL?我有一個通用的Java方法,具有以下方法簽名:private static ResultSet runSQLResultSet(String sql, Object... queryParams)它打開一個連接,PreparedStatement使用sql語句和queryParams變量長度數組中的參數構建一個,運行它,緩存ResultSet(在a中CachedRowSetImpl),關閉連接,并返回緩存的結果集。我在記錄錯誤的方法中有異常處理。我將sql語句記錄為日志的一部分,因為它對調試很有幫助。我的問題是記錄String變量會sql使用?而不是實際值記錄模板語句。我想記錄已執行(或嘗試執行)的實際語句。那么......有沒有辦法獲得將由a運行的實際SQL語句PreparedStatement?(沒有自己構建它。如果我找不到訪問PreparedStatement'sSQL的方法,我可能最終會自己構建它catch。)
查看完整描述

3 回答

?
元芳怎么了

TA貢獻1798條經驗 獲得超7個贊

使用預準備語句,沒有“SQL查詢”:

  • 您有一個包含占位符的聲明

    • 它被發送到DB服務器

    • 并在那里準備

    • 這意味著SQL語句被“分析”,解析,表示它的一些數據結構在內存中準備

  • 然后,你已經綁定了變量

    • 它們被發送到服務器

    • 并執行準備好的聲明 - 處理這些數據

但是沒有重構真正的實際SQL查詢 - 既不在Java端,也不在數據庫端。

因此,沒有辦法獲得準備好的語句的SQL - 因為沒有這樣的SQL。


出于調試目的,解決方案要么:

  • 使用占位符和數據列表輸出語句的代碼

  • 或者“手動”“構建”一些SQL查詢。


查看完整回答
反對 回復 2019-07-26
?
幕布斯6054654

TA貢獻1876條經驗 獲得超7個贊

它在JDBC API合同中沒有任何定義,但是如果你很幸運,有問題的JDBC驅動程序可以通過調用返回完整的SQL PreparedStatement#toString()。即

System.out.println(preparedStatement);

至少MySQL 5.x和PostgreSQL 8.x JDBC驅動程序支持它。但是,大多數其他JDBC驅動程序不支持它。如果你有這樣的,那么你最好的選擇是使用Log4jdbcP6Spy

或者,您也可以編寫一個泛型函數,它接受一個ConnectionSQL字符串和語句值,并PreparedStatement在記錄SQL字符串和值后返回一個。開球示例:

public static PreparedStatement prepareStatement(Connection connection, String sql, Object... values) throws SQLException {
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    for (int i = 0; i < values.length; i++) {
        preparedStatement.setObject(i + 1, values[i]);
    }
    logger.debug(sql + " " + Arrays.asList(values));
    return preparedStatement;}

并用它作為

try {
    connection = database.getConnection();
    preparedStatement = prepareStatement(connection, SQL, values);
    resultSet = preparedStatement.executeQuery();
    // ...

另一個替代方法是實現一個自定義PreparedStatement,它包裝(修飾)構造中的實際 PreparedStatement內容并覆蓋所有方法,以便它調用真實 的方法PreparedStatement并收集所有setXXX()方法中的值,并且懶惰地構造“實際”SQL字符串,只要其中一個executeXXX()調用這些方法(非常有用,但是大多數IDE為裝飾器方法提供了自動生成器,Eclipse確實如此)。最后只需使用它。這也基本上是P6Spy和配件已經在引擎蓋下做的事情。


查看完整回答
反對 回復 2019-07-26
?
開心每一天1111

TA貢獻1836條經驗 獲得超13個贊

我正在使用帶有MySQL連接器v.5.1.31的Java 8,JDBC驅動程序。

我可以使用此方法獲得真正的SQL字符串:

// 1. make connection somehow, it's conn variable// 2. make prepered statement templatePreparedStatement stmt = conn.prepareStatement(
    "INSERT INTO oc_manufacturer" +
    " SET" +
    " manufacturer_id = ?," +
    " name = ?," +
    " sort_order=0;");// 3. fill templatestmt.setInt(1, 23);stmt.setString(2, 'Google');// 4. print sql stringSystem.out.println(((JDBC4PreparedStatement)stmt).asSql());

所以它返回像這樣的smth:

INSERT INTO oc_manufacturer SET manufacturer_id = 23, name = 'Google', sort_order=0;


查看完整回答
反對 回復 2019-07-26
  • 3 回答
  • 0 關注
  • 4100 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號