понедельник, 17 марта 2014 г.

Чтение и запись данных поля XmlType в java с использованием Spring Jdbc

Напишу маленькую заметку чтобы самому не забыть. А для кого-то может оказаться полезным.
Мне потребовалось читать и писать данные в столбец таблицы с типом XmlType базы Oracle Database в виде строки.
При этом возникли 2 проблемы.

1) Чтение данных.
Проблема наблюдалась на версии Oracle Database 11.2.0.3.0. На версии 11.2.0.4.0 такой проблемы нет.
При чтении больших данных в Clob после 4000 символа появлялся 0-символ.
Чтение делалось запросом


select columnName.getClobVal() from tableName;

Самым простым решением было прочитать данные в Blob


select columnName.getBlobVal(nls_charset_id('UTF8')) from tableName;

2) Запись данных.
С записью данных оказалось сложнее. Чтобы записать данные более 4000 символов можно использовать специальное API от Oracle. Многие статьи в интернете ведут к этому.

Если не использовать это API, то возникают сложности.
Если пробовать различными способами вставлять данные более 4000 символов в базу, то можно получить всякие Exception. Мне постоянно вываливались:
ORA-01461: допускается привязка LONG значения только для занесения в столбец LONG

ORA-01461: can bind a LONG value only for insert into a LONG column
ORA-06553: PLS-307: too many declarations of 'CREATEXML' match this call

Решение проблемы:
Но начиная с java 1.6 и JDBC 4.0 API эта проблема решается проще. Blob и Clob можно создать с помощью метода java.sql.Connection#createBlob() и java.sql.Connection#createClob().
А в Spring Jdbc есть специальный класс обертка для работы с такими данными - org.springframework.jdbc.support.lob.DefaultLobHandler.

Использовать очень просто:

DefaultLobHandler lobHandler = new DefaultLobHandler();
lobHandler.setCreateTemporaryLob(true);    //Для поддержки текстов длиннее 4K.
sqlParameterSource.addValue("columnName", new SqlLobValue("Long long xml string...", lobHandler), Types.CLOB);

Сам Sql запрос выглядит таким образом:
update tableName set columnName = XMLTYPE.createXML(:columnName)

Комментариев нет:

Отправить комментарий