【问题标题】:JDBCTemplate close prepared statement after executing queryJDBCTemplate 执行查询后关闭准备好的语句
【发布时间】:2020-03-15 14:03:31
【问题描述】:

我想在完成数据库查询后关闭我的连接。问题是我正在使用准备好的语句,因为它们是预编译的,所以更安全。我想关闭数据库连接,以便以后可以将其重用于另一个查询。

文档说明如下:

/**
 * Create a statement in this connection. Allows implementations to use
 * PreparedStatements. The JdbcTemplate will close the created statement.
 * @param con the connection used to create statement
 * @return a prepared statement
 * @throws SQLException there is no need to catch SQLExceptions
 * that may be thrown in the implementation of this method.
 * The JdbcTemplate class will handle them.
 */
PreparedStatement createPreparedStatement(Connection con) throws SQLException;

我遇到了池中没有可用连接的情况。

我有以下但它抛出一个异常说在语句关闭后不允许任何操作。

private IRespondent InsertRespondentToken(IRespondent respondent) {
try{
    final String insertRespondent = "insert into respondents_token (SynchroID,TerminalID,QuestionnaireID,ProjectID,Token) values (?,?,?,?,?)";

    KeyHolder keyHolder = new GeneratedKeyHolder();
    jdbcTemplate.update(
            (Connection con) -> {
                try{
                    PreparedStatement pst = con.prepareStatement(insertRespondent, new String[] {"ID"});
                    pst.setInt(1, respondent.getSynchroId());
                    pst.setInt(2, respondent.getTerminalId());

                    pst.setInt(3, respondent.getQuestionnaireId());

                    pst.setInt(4,respondent.getProjectId());

                    respondent.setToken(GenerateUniqueId.getIdentifier());

                    pst.setString(5,respondent.getToken());

                    return pst;
                }
                catch (SQLException e)
                {
                    log.error("Prepared statement failed! Read the stack!",e);
                }
                finally {
                    con.close(); // IS thsi right. Or there is another way of doing it.
                }
                return null;
            }
            ,keyHolder);
    }catch(NullPointerException ex){
        log.error("Error during end element parsing.", ex);
        if (respondent.getId() != -1)
            deleteRespondent(respondent.getId());
        return null;
    }

  return respondent;
 }

【问题讨论】:

  • @Deadpool 我之前看到了那个帖子,但对我没有帮助。
  • 你使用的是哪个连接池?
  • Hikari 是我正在使用的连接池框架
  • JdbcTemplate 负责所有这些。从您的代码中删除try/catch,因为现在发生异常时可能会出错。如果您遇到这些情况,您可能会在自己的某个地方获得连接,而不是正确使用JdbcTemplate

标签: java database spring-boot jdbc


【解决方案1】:

您正在关闭连接,并通过扩展您创建的准备好的语句。所以当 JdbcTemplate 继续执行语句时,连接(和语句)已经关闭。您需要删除关闭连接的代码周围的try-catch-finally(并吞下任何异常)。

另请参阅 Spring 文档中的示例,Retrieving Auto-generated Keys 部分。您只需准备语句并填充其参数即可。

另一种看待这个问题的方式是使用资源管理的基本“规则”:您只关闭您创建的内容(除非另有说明)。在这种情况下,您没有创建连接,因此您不负责关闭它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多