java - 从 Derby 获取 PreparedStatement 查询

标签 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。我该怎么做呢?

最佳答案

通常 preparedStatement.toString() 会给你查询(包括绑定(bind)参数)。但这取决于 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

关于java - 从 Derby 获取 PreparedStatement 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36841864/

相关文章:

java - Log4j 在文件开头记录一些二进制信息

java - 即使输入相同,AES/CBC/NoPadding 是否会生成两个不同的密文?

java - @Basic(optional = false)在实体类编写中的用法

java - 将 Feign 与 Hystrix 结合使用时如何允许 400 错误传播?

java - 我在 Mac 上安装的 Java 11 中的 derby.jar 文件在哪里?

java - 连接到数据库,但我只获得默认模式,而不是我在原始系统上创建的模式。有任何想法吗?

java - 当事务仍处于 Activity 状态时无法关闭连接 connection.close() 上出现异常

使用缓冲区和线程进行 Java TCP byteArray 传输

java - Log4j:具有特化的多个类别

spring-boot - Debug模式下的 Spring Boot 日志不使用 log4j starter 打印