2016-04-25 15 views
2

私はデータベースに接続し、クエリを実行してクエリを出力しようとしています。これまでのところ、私は作品を持っているが、私は私のクエリをスパイするためにlog4jdbcを使用していた出力を取得し、StringDerbyからPreparedStatementクエリを取得

public static void main(String args[]) { 
     BasicConfigurator.configure(); 
     Logger.getGlobal().setLevel(Level.INFO); 
     PreparedStatement preparedStatement = null; 
     try { 
      connect(); 
      String sql = "SELECT * FROM foo WHERE ID = ?"; 
      preparedStatement = connection.prepareStatement(sql); 
      preparedStatement.setInt(1, 1); 
      try (ResultSet resultSet = preparedStatement.executeQuery()) { 
       while (resultSet.next()) { 
        break; 
       } 
      } 
      //String usedSql = "query should go here"; 
     } catch (SQLException ex) { 
      Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); 
     } finally { 
      if (preparedStatement != null) { 
       try { 
        preparedStatement.close(); 
       } catch (SQLException ex) { 
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 
      disconnect(); 
     } 
    } 

への特定の部分を割り当てる必要があります。私は​​にSELECT * FROM foo WHERE ID = 1を割り当てる

594 [main] DEBUG jdbc.foo - 1. Connection.new Connection returned java.sql.DriverManager.getConnection(DriverManager.java:664) 
608 [main] DEBUG jdbc.foo - 1. PreparedStatement.new PreparedStatement returned com.example.Test.main(Test.java:63) 
608 [main] DEBUG jdbc.foo - 1. Connection.prepareStatement(SELECT * FROM foo WHERE ID = ?) returned [email protected] com.example.Test.main(Test.java:63) 
608 [main] DEBUG jdbc.foo - 1. PreparedStatement.setInt(1, 1) returned com.example.Test.main(Test.java:64) 
608 [main] DEBUG jdbc.foo - 1. PreparedStatement.setMaxRows(1) returned com.example.Test.main(Test.java:65) 
609 [main] DEBUG jdbc.sqlonly - com.example.Test.main(Test.java:66) 
1. SELECT * FROM foo WHERE ID = 1 

:私はのような出力が記録されます瞬間

。これをやり遂げるにはどうすればいいですか?

+0

'preparedStatement.toStringは()'あなたに何を与えるのでしょうか? – Berger

+0

@Berger: 'net.sf.log4jdbc.PreparedStatementSpy @ 7d70d1b1' – Hooli

+0

これは既に回答済みです[こちら](http://stackoverflow.com/questions/2382532/how-can-i-get-the-sql- – soufrk

答えて

1

通常、preparedStatement.toString()はクエリ(バインドされたパラメータを含む)を提供します。しかし、それはPreparedStatementの実際の実装に依存します(例えば、PostgreSQLのimplを使った場合)。

あなたは、preparedStatement.toString()[email protected]を返すと述べました。私はlog4jdbcに慣れていませんが、PreparedStatementSpyは実際のPreparedStatementをラップしているようです。あなたのpreparedStatementからそれを取得するには、編集

if(preparedStatement instanceof PreparedStatementSpy) 
    usedSql = ((PreparedStatementSpy) preparedStatement).getRealStatement().toString(); 

のようなものを試してください:あなたはダービーシンプルtoString()行うことはありませんを使用しているため。この場合、PreparedStatementSpy.dumpedSql()を使用すると、同じ文字列を返すことがあります。log4jdbcログの記録に使用します。残念ながら、その方法を保護し、あなたは、リフレクションを使用する必要があります。

if (preparedStatement instanceof PreparedStatementSpy) { 
    Method m = PreparedStatementSpy.class.getDeclaredMethod("dumpedSql"); 
    m.setAccessible(true); 
    usedSql = (String) m.invoke(preparedStatement); 
} 
// omitted exception handling 
+0

PreparedStatementは、ターゲット・ステートメントにアクセスする別の方法かもしれない[java.sql.Wrapper](https://docs.oracle.com/javase/7/docs/api/java/sql/Wrapper.html)を実装しています。 – jmehrens

+0

これは最速のため、私はderby埋め込みを使用しています。私は 'PreparedStatementSpy'が何であるか分かりませんが、log4jdbcはデータベースとアプリケーション間のプロキシとして機能し、それらの間の通信に関する追加情報を提供します。 – Hooli

+0

@Hooliは、Derbyで動作する可能性のある例を更新しました – nyname00

関連する問題