Reading a `BLOB` via JDBC takes too long
When I read an image from database, it appears in the JLabel immediately, but it takes too much time to complete streaming the BLOB开发者_开发问答 from the DB.
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;
}
Consider storing the image outside of the database. Only store enough info in the DB to let you find the file (either on the filesystem, or from an HTTP server, or however you're storing it now that it's not in the DB). Binary data isn't really the use case that an RDBMS is optimized to handle.
Also, your code has some serious problems:
The biggest problem is probably the security flaw you get by failing to use bind variables, a.k.a. a
PreparedStatementin Java. This is SQL injection 101.you're using raw JDBC. Raw JDBC is tedious and easy to mess up. For instance, you aren't closing your
ResultSetor yourConnection, not to mention thestatementvariable, which should definitely be local. And when you do start closing them, you should do it in afinallyblock to make sure it always happens, even if there is an error.If you happen to get more than one result from your query—I'm guessing you shouldn't, but just in case—you will only know if you happen to look at
STDOUT, and you'll just get the last image. Yourwhileloop is probably better expressed as anifto indicate that you only expect and/or care about the first result. If you care if there is more than one results, you should probably use anifinstead of a while, then add a subsequentif (rs.next()) throw new MyAppropriatelyNamedException;so you know that there is something unexpected going on.The
nullcheck forresis worthless. By the time you execute the check, thers.next()statement will have already thrown aNullPointerException. You should probably just delete the check.Why are you using the logging framework, only to turn around and use
System.out.printlnto output some debugging info?
加载中,请稍侯......
精彩评论