从Derby获取PreparedStatement查询

时间:2016-04-25 13:22:56

标签: java log4j derby slf4j log4jdbc

我正在尝试连接数据库,运行查询并打印出查询。到目前为止我的工作是什么,但我需要获取输出并将其中的特定部分分配给String

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 net.sf.log4jdbc.PreparedStatementSpy@7d70d1b1  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。我怎么能这样做呢?

1 个答案:

答案 0 :(得分:1)

通常preparedStatement.toString()会给你查询(包括绑定参数)。但这取决于PreparedStatement的实际实现(例如,PostgreSQL impl有效)。

您提到preparedStatement.toString()会为您返回net.sf.log4jdbc.PreparedStatementSpy@7d70d1b1。我不熟悉 log4jdbc ,但看起来PreparedStatementSpy正在包裹您的实际PreparedStatement。要从preparedStatement尝试使用

这样的内容
if(preparedStatement instanceof PreparedStatementSpy)
     usedSql = ((PreparedStatementSpy) preparedStatement).getRealStatement().toString();

修改:因为您正在使用 Derby ,所以我们不会使用简单的toString()。解决这个问题的方法可能是使用PreparedStatementSpy.dumpedSql(),它将返回 log4jdbc 用于记录的相同字符串。不幸的是,它是 protected 方法,你必须使用反射:

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