通过JDBC读取“BLOB”需要太长时间

时间:2011-01-19 13:35:53

标签: 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);
    } 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;
}

1 个答案:

答案 0 :(得分:3)

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

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

  1. 最大的问题可能是你在Java中使用绑定变量a.k.a. a PreparedStatement时遇到的安全漏洞。这是SQL注入101。

  2. 您正在使用原始JDBC。原始的JDBC很乏味且容易搞砸。例如,您没有关闭ResultSetConnection,更不用说statement变量,它应该是本地变量。当你开始关闭它们时,你应该在finally块中进行,以确保它始终发生,即使出现错误。

  3. 如果您碰巧从查询中得到多个结果 - 我猜你不应该这样做,但为了以防万一 - 你只会知道你是否碰巧看到了STDOUT,你会得到最后一张图片。您的while循环可能更好地表示为if,表示您只期望和/或关心第一个结果。如果你关心是否有多个结果,你可能应该使用if而不是一段时间,然后添加一个后续的if (rs.next()) throw new MyAppropriatelyNamedException;,这样你就知道有一些意想不到的事情发生了。

  4. null的{​​{1}}检查毫无价值。当您执行检查时,res语句已经抛出rs.next()。您应该删除支票。

  5. 为什么使用日志框架,只是转身并使用NullPointerException输出一些调试信息?