Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过JDBC读取“BLOB”花费的时间太长_Java_Blob - Fatal编程技术网

Java 通过JDBC读取“BLOB”花费的时间太长

Java 通过JDBC读取“BLOB”花费的时间太长,java,blob,Java,Blob,当我从数据库中读取图像时,它会立即出现在JLabel中,但要从数据库中完成BLOB流式传输需要花费太多时间 public byte[] selectImage(int Id) throws SQLException { ResultSet res=null; int c=0; try { Class.forName(driver); con = DriverManager.getConnection(connectionURL);

当我从数据库中读取图像时,它会立即出现在
JLabel
中,但要从数据库中完成
BLOB
流式传输需要花费太多时间

public byte[] selectImage(int Id) throws SQLException {
    ResultSet res=null;
    int c=0;

    try {
        Class.forName(driver);
        con = DriverManager.getConnection(connectionURL);
    } catch (SQLException ex) {
        Logger.getLogger(Connect.class.getName()).log(Level.SEVERE, null, ex);
    } catch (ClassNotFoundException ex) {
        Logger.getLogger(Connect.class.getName()).log(Level.SEVERE, null, ex);
    }

    System.out.println(con.getAutoCommit());

    statement = con.createStatement() ;
    res = statement.executeQuery("SELECT PHOTO FROM CUSTOMER where ID="+Id) ;

    while(res.next() && (res!=null)) {
        Blob bodyOut = res.getBlob("PHOTO");
        int length = (int) bodyOut.length();
        System.out.println("   Body Size = "+length);
        imageBytes = bodyOut.getBytes(1, length);
        bodyOut.free(); 
    }

    return imageBytes;
}

考虑将图像存储在数据库之外。只在数据库中存储足够的信息,以便您查找文件(在文件系统上,或从HTTP服务器,或以不在数据库中的方式存储)。二进制数据实际上不是RDBMS优化处理的用例

此外,您的代码还存在一些严重问题:

  • 最大的问题可能是由于未能使用绑定变量(在Java中也称为绑定变量)而导致的安全缺陷。这是SQL注入101

  • 您正在使用原始JDBC。原始JDBC很乏味,而且很容易搞糟。例如,您没有关闭
    结果集
    连接
    ,更不用说
    语句
    变量了,它肯定是本地变量。当您开始关闭它们时,您应该在
    finally
    块中执行此操作,以确保它始终发生,即使出现错误

  • 如果您碰巧从查询中得到了多个结果,我猜您不应该这样做,但以防万一,您只会知道您是否碰巧看到了STDOUT,并且只会得到最后一张图像。您的
    while
    循环最好表示为
    if
    ,表示您只期望和/或关心第一个结果。如果您关心是否有多个结果,您可能应该使用
    If
    而不是while,然后添加一个后续的
    If(rs.next())抛出新的mypropertlyNamedexception这样您就知道发生了意想不到的事情

  • null
    检查
    res
    毫无价值。当您执行检查时,
    rs.next()
    语句将已经抛出
    NullPointerException
    。您可能应该删除支票

  • 为什么您要使用日志框架,只是为了返回并使用
    System.out.println
    输出一些调试信息


  • 这几乎就像你不应该在数据库中存储图像数据——只是对磁盘上文件的引用。阅读以获取更多信息。根据图像和访问模式,在数据库中存储blob有时可能更快。阅读这篇有趣的文章:(与SQL Server相关,但如果这同样适用于其他DBMS,我也不会感到惊讶)@a_horse_与_no_名称一样,每种情况都有其独特的细微差别,但是,将二进制数据放入数据库应该是对一般规则的一个经过仔细论证的例外:不要将二进制数据放入RDBMS。就个人而言,我在将BLOB放入数据库方面有很好的经验。它使生活变得更加轻松(没有文件系统清理,没有权限问题,单个数据库备份包含所有内容,存储它们是事务安全的,不必担心在目录层次结构上分发1.000.000个文件)。但我同意,对于大图像,它会给数据库带来不必要的负担。但是,现代的数据库管理系统确实可以非常有效地处理这个问题well@a_horse_with_no_name正如我所说,每种情况都是不同的。在我的例子中,将文件放入数据库是没有意义的,因为它们将由Web服务器提供服务。如果Web服务器已经针对文件服务进行了优化,那么为什么要浪费资源将内容放入数据库并进行查找呢?此外,您经常会以不同于数据库中常规数据的方式对待二进制资源:单独的表空间、不同的备份策略等。可能最好让讨论涵盖细节。我完全同意,尤其是考虑到每种情况都是不同的;)