java - 什么时候关闭 PreparedStatement.setBlob 使用的 InputStream 是安全的?

标签 java mysql jdbc

PreparedStatement.setBlobPreparedStatement.setBinaryStream 和少数其他 PreparedStatement 方法可以从 中读取查询数据输入流。不幸的是,文档对何时读取数据一点也不清楚。它只是说

data will be read from the stream as needed until end-of-file is reached.

对于何时需要数据,我可以想到三种可能的解释:

  • 在调用 setBlob(或其他具有 InputStream 参数的方法)返回之前
  • 语句执行时
  • 事务提交时

那么,在什么时候关闭 InputStream(或相关 InputStream 所依赖的其他资源)是安全的?它是否取决于驱动程序(我目前正在使用 MySQL,但由于我希望保持开放的迁移可能性,因此了解其他驱动程序如何处理它可能也很好)?

最佳答案

写了一个简单的例子来在本地用 MySQL 测试这个(原谅糟糕的异常处理):

public void testInputStream(String filePath) throws SQLException, IOException {
    DBUtil util = new DBUtil();//just a simple connection util
    Connection conn = util.getConnection("test");

    conn.setAutoCommit(false);

    File file = new File(filePath);
    FileInputStream fis = null;

    fis = new FileInputStream(file);

    String sql = "insert into testtable(scol,lob) values(?,?)";
    PreparedStatement stmt = conn.prepareStatement(sql);
    stmt.setString(1, "number4!");
    stmt.setBlob(2, fis);
    //fis.close() //this throws an exception
    stmt.executeUpdate();
    fis.close();//no exception here
    conn.commit();
    //fis.close();//no exception when called here
    stmt.close();
}

testtable 是一个非常简单的表:

create table testtable (
    id int auto_increment primary key,
    scol varchar(50),
    lob blob
)engine=innodb;

语句执行后似乎也是我测试的正确答案。它可能会因驱动程序而异,但我认为在执行查询之前关闭 InputStream 的任何情况都不会起作用。翻阅MySQL的源代码后PreparedStatement它看起来很简单;它需要打开流来调用 sendPacket()(在执行实际执行的幕后方法下),但在 executeUpdate() 完成后,流对象显示为空闲。

我认为您可以安全地假设此行为在几乎 任何实现 JDBC 规范的驱动程序中都是一致的。那里可能有一些异常(exception),但如果它们支持 InputStream,它应该以相同的方式工作。

关于java - 什么时候关闭 PreparedStatement.setBlob 使用的 InputStream 是安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21360131/

相关文章:

java - MySQL JDBC 连接器转义问题

java - Hibernate Group by Criteria Object

java - 用oozie触发Pig工作

java - 如何将值从 Button.setOnClickListener 传递到 onDateSet Android

php - 数据读取器mysql

php - MySQL - 查找表上事务最多的客户端

python - 获取 Pandas 中共享唯一标识符的一系列行中单元格的最新值

java - 如何沿 X 轴移动 JFrame?

java - JSF 与数据库交互

mysql - Servlet-数据库连接问题