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

发布于 2024-10-12 18:23:44 字数 1010 浏览 2 评论 0原文

当我从数据库读取图像时,它会立即出现在 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;
}

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

公布 2024-10-19 18:23:44

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

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

  1. 最大的问题可能是由于未能使用绑定变量而导致的安全缺陷,又名 PreparedStatement。这是 SQL 注入 101。

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

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

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

  5. 为什么使用日志框架,只是为了转而使用 System.out.println 来输出一些调试信息?

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:

  1. 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.

  2. you're using raw JDBC. Raw JDBC is tedious and easy to mess up. For instance, you aren't closing your ResultSet or your Connection, not to mention the statement variable, which should definitely be local. And when you do start closing them, you should do it in a finally block to make sure it always happens, even if there is an error.

  3. 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. Your while loop is probably better expressed as an if 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 an if instead of a while, then add a subsequent if (rs.next()) throw new MyAppropriatelyNamedException; so you know that there is something unexpected going on.

  4. The null check for res is worthless. By the time you execute the check, the rs.next() statement will have already thrown a NullPointerException. You should probably just delete the check.

  5. Why are you using the logging framework, only to turn around and use System.out.println to output some debugging info?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文