[an error occurred while processing this directive] IT • archiv :: Print

IT • archiv


[an error occurred while processing this directive]

[an error occurred while processing this directive]

Особенности работы с Blob для Oracle и Oracle Lite

[an error occurred while processing this directive](none) [an error occurred while processing this directive](none)[an error occurred while processing this directive] ::
[an error occurred while processing this directive](none)
[an error occurred while processing this directive]([an error occurred while processing this directive] Роман Агафонов [an error occurred while processing this directive])

[an error occurred while processing this directive](none)
PDF versionPDF версия

Думаю, любой программист-разработчик так или иначе в своей карьере сталкивается с разработкой софта под базы данных. Многие только этим и занимаются. Самостоятельно натыкаются на подводные камни, связанные с особенностями используемой БД, и также самостоятельно пытаются их преодолеть. В принципе, стандартные средства Java избавили разработчиков от большинства проблем, и библиотека java.sql с успехом исчерпывает основную массу потребностей, но всегда есть нюансы, которые такими средствами не решаются, и, как правило, именно они больше всего интересуют программистов.

В данной статье я коснусь особенностей закачки и получения блобов в Oracle и Oracle Lite. В Oracle есть странноватая особенность, заключающаяся в том, что для того, чтобы вставить в таблицу Blob, надо сначала получить его из этой же таблицы. Соответственно, чтобы добавить новые данные в поле типа Blob, предварительно придется создать пустую запись типа Blob, а потом уже ее выдергивать из таблицы для использования в своих корыстных целях. Выглядит это примерно так:

//создаем запись с пустым значением в поле типа Blob
Statement stmn=oracleCon.createStatement();
stmn.execute("insert into TABLE (BLOBDATA)
 values (empty_blob())");

//получаем объект типа BLOB
ResultSet rs=stmn.executeQuery(
 "select BLOBDATA from TABLE where PRKEY=? for
update");
oracle.sql.BLOB blob = null;
while (rs.next()) {
blob = ((oracle.jdbc.driver.OracleResultSet)
  rsBlob).getBLOB(1);

blob.putBytes(…);

}
rs.close();
st.close();

//для закачки в Oracle содержания блоба
PreparedStatement ps=oracleCon.
 prepareStatement("update TABLE set BLOBDATA=?
where PRKEY=?");

//делаем update нашего BLOB
ps.setBlob(1, blob);
ps.setObject(2,keyvalue);
ps.executeUpdate();
ps.close();

При закачке в Blob массива данных нужно использовать именно oracle.sql.BLOB.putBytes(…). Стандартный метод java.sql.Blob.setBytes(…) при массивах данных больших 1 мегабайта работает некорректно.

Теперь разберем Oracle Lite. Особенность заключается в том, что Oracle Lite вообще криво работает с данными типа Blob, хотя вроде бы и поддерживает оные. Как альтернативу предлагается использовать тип Long Raw, с ним проблем пока не наблюдалось — и объемы держит, и в обращении (с точки зрения программного кода) даже попроще чем Blob.

При получении данных из поля типа Long Raw java определяет их как массив байтов, но если нам нужно закачать данные, то необходимо представлять наш объект как бинарный поток. Использование метода PreparedStatement.setBytes(…) не только не совсем корректно, но даже пару раз у меня подвешивало всю базу. Для наглядности привожу кратенький пример корректного кода:

byte[] value  //наш исходный массив байтов
PreparedStatement psLite = liteCon.prepareStatement(
 "insert into TABLE (BLOBDATA)
values(?)");
InputStream is=new ByteArrayInputStream(value);
psLite.setBinaryStream(1, in, value.length);
psLite.executeUpdate();
psLite.close();
is.close();
[an error occurred while processing this directive]
[an error occurred while processing this directive](none)
< Вернуться на caйт :: Copyright © 1999 — 2010, IT • archiv.