2016-04-25 4 views
2

Я пытаюсь подключиться к базе данных, запустить запрос и распечатать запрос. До сих пор, что у меня есть дела, но мне нужно, чтобы получить выход и назначить определенную часть его к Stringполучить запрос PreparedStatement от Derby

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(); 
     } 
    } 

Я использую log4jdbc, чтобы следить за своими запросами.

На данный момент я получаю зафиксированная выход как:

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 

Я хочу, чтобы назначить SELECT * FROM foo WHERE ID = 1 к usedSql. Как я могу это сделать?

+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(); 

Edit: так как вы используете Derby простой 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 embedded, потому что это самый быстрый. Я не уверен, что такое 'PreparedStatementSpy', но log4jdbc действует как прокси-сервер между базой данных и вашим приложением, чтобы предоставить дополнительную информацию о связях между ними. – Hooli

+0

@Hooli см. Мое обновление для примера, который мог бы работать с 'Derby' – nyname00