当我从数据库中读取图像时,它会立即显示在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;
}
答案 0 :(得分:3)
考虑将图像存储在数据库之外。只在DB中存储足够的信息以便您找到文件(在文件系统上,或从HTTP服务器上,或者您现在存储它不在数据库中)。二进制数据实际上并不是RDBMS优化处理的用例。
此外,您的代码存在一些严重问题:
最大的问题可能是你在Java中使用绑定变量a.k.a. a PreparedStatement
时遇到的安全漏洞。这是SQL注入101。
您正在使用原始JDBC。原始的JDBC很乏味且容易搞砸。例如,您没有关闭ResultSet
或Connection
,更不用说statement
变量,它应该是本地变量。当你开始关闭它们时,你应该在finally
块中进行,以确保它始终发生,即使出现错误。
如果您碰巧从查询中得到多个结果 - 我猜你不应该这样做,但为了以防万一 - 你只会知道你是否碰巧看到了STDOUT
,你会得到最后一张图片。您的while
循环可能更好地表示为if
,表示您只期望和/或关心第一个结果。如果你关心是否有多个结果,你可能应该使用if
而不是一段时间,然后添加一个后续的if (rs.next()) throw new MyAppropriatelyNamedException;
,这样你就知道有一些意想不到的事情发生了。
对null
的{{1}}检查毫无价值。当您执行检查时,res
语句已经抛出rs.next()
。您应该删除支票。
为什么使用日志框架,只是转身并使用NullPointerException
输出一些调试信息?