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
PreparedStatement
in 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
ResultSet
or yourConnection
, not to mention thestatement
variable, which should definitely be local. And when you do start closing them, you should do it in afinally
block 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. Yourwhile
loop is probably better expressed as anif
to 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 anif
instead of a while, then add a subsequentif (rs.next()) throw new MyAppropriatelyNamedException;
so you know that there is something unexpected going on.The
null
check forres
is 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.println
to output some debugging info?
精彩评论