3 回答

TA貢獻(xiàn)1798條經(jīng)驗(yàn) 獲得超7個(gè)贊
使用預(yù)準(zhǔn)備語(yǔ)句,沒(méi)有“SQL查詢(xún)”:
您有一個(gè)包含占位符的聲明
它被發(fā)送到DB服務(wù)器
并在那里準(zhǔn)備
這意味著SQL語(yǔ)句被“分析”,解析,表示它的一些數(shù)據(jù)結(jié)構(gòu)在內(nèi)存中準(zhǔn)備
然后,你已經(jīng)綁定了變量
它們被發(fā)送到服務(wù)器
并執(zhí)行準(zhǔn)備好的聲明 - 處理這些數(shù)據(jù)
但是沒(méi)有重構(gòu)真正的實(shí)際SQL查詢(xún) - 既不在Java端,也不在數(shù)據(jù)庫(kù)端。
因此,沒(méi)有辦法獲得準(zhǔn)備好的語(yǔ)句的SQL - 因?yàn)闆](méi)有這樣的SQL。
出于調(diào)試目的,解決方案要么:
使用占位符和數(shù)據(jù)列表輸出語(yǔ)句的代碼
或者“手動(dòng)”“構(gòu)建”一些SQL查詢(xún)。

TA貢獻(xiàn)1876條經(jīng)驗(yàn) 獲得超7個(gè)贊
它在JDBC API合同中沒(méi)有任何定義,但是如果你很幸運(yùn),有問(wèn)題的JDBC驅(qū)動(dòng)程序可以通過(guò)調(diào)用返回完整的SQL PreparedStatement#toString()
。即
System.out.println(preparedStatement);
至少M(fèi)ySQL 5.x和PostgreSQL 8.x JDBC驅(qū)動(dòng)程序支持它。但是,大多數(shù)其他JDBC驅(qū)動(dòng)程序不支持它。如果你有這樣的,那么你最好的選擇是使用Log4jdbc或P6Spy。
或者,您也可以編寫(xiě)一個(gè)泛型函數(shù),它接受一個(gè)Connection
SQL字符串和語(yǔ)句值,并PreparedStatement
在記錄SQL字符串和值后返回一個(gè)。開(kāi)球示例:
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(); // ...
另一個(gè)替代方法是實(shí)現(xiàn)一個(gè)自定義PreparedStatement
,它包裝(修飾)構(gòu)造中的實(shí)際 PreparedStatement
內(nèi)容并覆蓋所有方法,以便它調(diào)用真實(shí) 的方法PreparedStatement
并收集所有setXXX()
方法中的值,并且懶惰地構(gòu)造“實(shí)際”SQL字符串,只要其中一個(gè)executeXXX()
調(diào)用這些方法(非常有用,但是大多數(shù)IDE為裝飾器方法提供了自動(dòng)生成器,Eclipse確實(shí)如此)。最后只需使用它。這也基本上是P6Spy和配件已經(jīng)在引擎蓋下做的事情。

TA貢獻(xiàn)1836條經(jīng)驗(yàn) 獲得超13個(gè)贊
我正在使用帶有MySQL連接器v.5.1.31的Java 8,JDBC驅(qū)動(dòng)程序。
我可以使用此方法獲得真正的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;
添加回答
舉報(bào)