Чтение BLOB через JDBC занимает слишком много времени - PullRequest
1 голос
/ 19 января 2011

Когда я читаю изображение из базы данных, оно сразу появляется в 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 Ответ

3 голосов
/ 19 января 2011

Рассмотрите возможность хранения изображения вне базы данных. Храните только достаточно информации в БД, чтобы вы могли найти файл (либо в файловой системе, либо с HTTP-сервера, либо вы храните его сейчас, когда его нет в БД). Двоичные данные на самом деле не тот случай использования, который оптимизирована для обработки СУБД.

Кроме того, у вашего кода есть серьезные проблемы:

  1. Самой большой проблемой, вероятно, является уязвимость, которую вы получаете, отказываясь использовать переменные связывания, a.k.a. PreparedStatement в Java. Это SQL-инъекция 101.

  2. вы используете сырой JDBC. Сырой JDBC утомителен и легко испортить. Например, вы не закрываете ResultSet или Connection, не говоря уже о переменной statement, которая определенно должна быть локальной. И когда вы начнете закрывать их, вы должны сделать это в блоке finally, чтобы убедиться, что это всегда происходит, даже если есть ошибка.

  3. Если вам случится получить более одного результата из вашего запроса - я полагаю, вы не должны этого делать, но на всякий случай - вы будете знать только, если вам случится взглянуть на STDOUT, и вы ' Я просто получу последнее изображение. Ваш цикл while, вероятно, лучше выразить в виде if, чтобы указать, что вы ожидаете и / или заботитесь только о первом результате. Если вас волнует, если есть более одного результата, вам, вероятно, следует использовать if вместо некоторого времени, а затем добавить последующий if (rs.next()) throw new MyAppropriatelyNamedException;, чтобы вы знали, что происходит что-то неожиданное.

  4. Проверка null на res ничего не стоит. К тому времени, когда вы выполните проверку, оператор rs.next() уже сгенерирует NullPointerException. Вы, вероятно, должны просто удалить чек.

  5. Почему вы используете каркас журналирования, только чтобы развернуться и использовать System.out.println для вывода некоторой отладочной информации?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...