java.sql.SQLException:无法在PreparedStatement上调用方法

问题描述 投票:0回答:1

我想使用 HikariCP 使用 SQLite 连接到 SQLite 数据库。 但是当我尝试运行查询时出现错误。

Exception in thread "main" java.lang.RuntimeException: java.sql.SQLException: method cannot be called on a PreparedStatement
    at StatementUtility.wrapException(StatementUtility.java:110)
    at StatementUtility.executeUpdate(StatementUtility.java:101)
    at Database.createTables(Database.java:27)
    at Database.<init>(Database.java:23)
    at Main.main(Main.java:10)

Hikari 连接设置:

public Client () {
    HikariConfig config = new HikariConfig();
    config.setPoolName("AuthMeSQLitePool");
    config.setDriverClassName("org.sqlite.JDBC");
    config.setConnectionTestQuery("SELECT 1");
    config.setJdbcUrl("jdbc:sqlite:I:/data.db");
    config.setMaxLifetime(60000);
    config.setIdleTimeout(45000);
    config.setMaximumPoolSize(50);
}

StatementUtility.java:

public <R> R executeQuery(String sql, ThrowingConsumer<PreparedStatement> cfg, ThrowingFunction<ResultSet, R, SQLException> op) {
    return wrapException(sql, s -> {
        cfg.accept(s);
        return op.apply(s.executeQuery());
    });
}

public int executeUpdate(String sql, ThrowingConsumer<PreparedStatement> cfg) {
    return wrapException(sql, s -> {
        cfg.accept(s);
        return s.executeUpdate();
    });
}

public <R> R executeQuery(String sql, ThrowingFunction<ResultSet, R, SQLException> op) {
    return wrapException(sql, s -> op.apply(s.executeQuery(sql)));
}

public int executeUpdate(String sql) {
    return wrapException(sql, s -> s.executeUpdate(sql));
}

private <T> T wrapException(String sql, @NotNull ThrowingFunction<PreparedStatement, T, SQLException> operation) {
    try(Connection connection = getConnection()){
        try (PreparedStatement statement = connection.prepareStatement(sql)) {
            return operation.apply(statement);
        }
    } catch (SQLException e) {
        throw new RuntimeException(e);
    }
}

@FunctionalInterface
public interface ThrowingConsumer<T> extends Consumer<T> {

    @Override
    default void accept(final T elem) {
        try {
            acceptThrows(elem);
        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
    }

    void acceptThrows(T elem) throws Exception;
}

@FunctionalInterface
public interface ThrowingFunction<T, R, E extends Exception> {
    R apply(T input) throws E;
}

它适用于本机查询语句执行,因此不是与连接相关的问题。有什么想法吗?

java sqlite jdbc prepared-statement
1个回答
0
投票

问题是您的某些方法在

executeQuery(String)
上调用
executeUpdate(String)
PreparedStatement
,这是 JDBC API 不允许的。如果发生这种情况,符合要求的实现需要抛出
SQLException

Statement.executeQuery(String)
(强调我的)中记录:

投掷:

SQLException
- 如果发生数据库访问错误,则在关闭的
Statement
上调用此方法,给定的 SQL 语句生成除单个
ResultSet
对象之外的任何内容,
PreparedStatement
CallableStatement 上调用该方法

execute
上的其他
Statement
方法也有同样的记录。

您需要使用

executeQuery()
executeUpdate()
,或者您需要使用
Statement
而不是
PreparedStatement

© www.soinside.com 2019 - 2024. All rights reserved.