Питанням використання великих об'єктів LOB (Large Object Bynary) найчастіше доводиться приділяти пильну увагу. Пов'язано це зі зберіганням різних файлів в таблицях бази даних (БД). Відразу ж виникає питання, навіщо зберігати в БД файл, якщо потім доведеться витягувати його назад знову ж у вигляді в файлу? Адже можна створити окреме файлове сховище. Відповідь також виявляється простим і тривіальним - для файлового сховища потрібно додатково вирішувати питання реплікації і синхронізації, надання прав доступу та створення backup'a. Таким чином, якщо не можна обійтися без LOB-об'єктів, то залишається вибрати їх тип - бінарний (BLOB Binary Large Object) або символьний, званий в БД різних провайдерів по-різному (CLOB, TEXT).
ПРИМІТКА. при роботі з символьними даними необхідно враховувати кодування. Це питання буде врахований під час запису текстового файлу в таблиці БД і вивантаження з БД.
опис прикладу
У статті розглядається приклад запису і читання декількох типів файлів в поля BLOB і CLOB (TEXT). Як сервери БД були використані Oracle 10g Enterprise Edition, Oracle 10g Express Edition і MySQL 5.1.
Приклад являє собою проект Eclipse, який реалізує всі принципи ООП (об'єктно-орієнтоване програмування) - успадкування, інкапсуляція і поліморфізм. Структура проекту представлена на наступному скріншоті.
У директорії «lib» розміщуються бібліотеки JDBC для підключення до серверів БД. При підключенні до сервера 10g Enterprise Edition використовувалася бібліотека ojdbc7.jar. У разі використання сервера 10g Express Edition були використані бібліотеки ojdbc14_g.jar, ojdbc14.jar. Для підключення в IDE Eclipse бібліотеки до проекту необхідно її виділити і в контекстному меню вибрати "Build Path / Add to Build Path". Щоб відключити використання бібліотеки в проекті використовуйте вкладку "Java Build Path" у вікні властивостей проекту.
Приклад включає наступні програмні модулі:
базовий модуль створення підключення до сервера БД і роботи з полями BLOB і CLOB (TEXT);
Читання об'єкта CLOB
Параметри процедур запису і читання великих об'єктів LOB включають найменування таблиць table. найменування LOB-полів field. найменування поля первинного ключа pk. ідентифікатор запису id і шлях до файлу fpath. При необхідності Ви можете доопрацювати дані процедури і включити в якості параметра найменування схеми Schema (Oracle) або бази даних Database (MySQL). Не виключено, що і первинний ключ може містити кілька полів.
ПРИМІТКА.
1. Слід звернути увагу, що методи роботи з полями BLOB і CLOB не переважають згідно з поданою вище таблиці. Але це стосується баз даних Oracle і MySQL, які використовуються в прикладі. Тобто можна сказати, що методи JDBC «справляються» з полями LOB даних провайдерів. До того ж в MySQL використовується тип TEXT, а в Oracle CLOB.
2. Можна використовувати різні методи запису в поля LOB вміст файлів, що буде продемонстровано на прикладі MySQL.
Нижче представлений лістинг DAOBase.java, де методи роботи з полями BLOB і CLOB не включають код. Це зроблено навмисно для наочного уявлення загальної структури модуля DAOBase.java. В іншому випадку лістинг сильно збільшиться і «за деревами не можна буде побачити ліс». Код методів роботи з полями LOB описаний далі.
лістинг DAOBase.java
Процедури створення createTable (sql) і видалення dropTable (sql) таблиці БД не включені в загальний список методів DAOBase.java, оскільки в прикладі виконують допоміжну функцію і використовується для «підігравання». Як правило, структура БД змінюється рідко і немає необхідності включати в додаток процедури, які не використовуються.
Лістинг методів читання і запису даних в поле BLOB
Дві допоміжні функції readBlobField і writeFromBlob2Stream мають модифікатори private і застосовуються головним методом readBlobToFile при вивантаженні файлу з БД.
Для запису файлу в поле BLOB використовується метод setBinaryStream. який одержує в якості параметра потік FileInputStream. При вивантаженні файлу з БД в методі readBlobToFile спочатку читається об'єкт BLOB (readBlobField), після цього він записується в вихідний потік OutputStream в методі writeFromBlob2Stream, де використовується метод читання в бінарний потік getBinaryStream () об'єкта BLOB.
Лістинг процедур читання і запису даних в поле CLOB
Дві допоміжні функції readClobField і readFromClob2Stream мають модифікатори private і використовуються основними методами readClobToFile. readClobData при вивантаженні файлу з БД.
Щоб врахувати кодування символів під час запису текстового файлу в БД використовується InputStreamReader і BufferedReader. Для запису файлу в поле CLOB / TEXT використовується метод setCharacterStream об'єкта CLOB. якому передається BufferedReader. При вивантаженні файлу з БД в методі readClobToFile спочатку читається об'єкт CLOB (readClobField), після цього він записується в вихідний потік BufferedWriter в методі readFromClob2Stream, де використовується метод читання в символьний потік getCharacterStream () об'єкта CLOB.
лістинг OracleDAO.java
Лістинг модуля OracleDAO.java включає перевизначені метод createConnection () і метод створення процедур БД createTable. Структури таблиць, описані в константах TABLE_blobs і TABLE_files у вигляді SQL-скриптів, включають тільки поля ідентифікаторів id і поля data відповідних типів LOB. За замовчуванням поля дата мають значення NULL, оскільки використовуються в методах при оновленні.
При створенні об'єкта в конструкторі відразу ж створюється підключення до сервера БД. Як властивості об'єкту підключення передається кодування встановлюваного з'єднання "utf8".
лістинг MySQLDAO.java
Лістинг модуля MySQLDAO.java включає перевизначені метод createConnection (). метод створення процедур БД createTable і метод writeClob. який демонструє інший підхід записи символьного файлу в поле TEXT. В даному методі файловий потік FileInputStream відразу ж перенаправляється в потік setAsciiStream. Але щоб не спотворити символи використовувати відповідну кодування в таблиці БД та підключенні до сервера. Батьківський метод writeClob класу DAOBase.java також спрацював без нарікань. Таким чином, у Вашому розпорядженні 2 підходи записи текстового файлу в БД MySQL.
Структури таблиць, описані в константах TABLE_blobs і TABLE_files у вигляді SQL-скриптів, включають тільки поля ідентифікаторів id і поля data відповідних типів LOB. Для таблиці "files" встановлена кодування "UTF8". За замовчуванням поля дата мають значення NULL, тому що використовуються в методах при оновленні.
При створенні об'єкта в конструкторі відразу ж створюється підключення до сервера БД, якому в якості властивості передається кодування встановлюваного з'єднання "utf8".
тестування прикладу
Головний модуль додатка MainTest.java виконує тестування методів запису файлів в БД і вивантаження в файл. Основний метод тестування testDAO як параметр приймає базовий клас (поліморфізм). У методі testDAO спочатку перевіряється установка з'єднання з сервером БД. Після підключення, то створюються таблиці, в які записуються і витягуються файли.
Результати тестування
Додаток виводить повідомлення і результати тестування методів запису і читання LOB-об'єктів в консоль.
завантажити приклад
Вихідний код розглянутого прикладу записи і читання великих об'єктів LOB з використанням JDBC можна скачати тут (7.27 Мб).
При тестуванні прикладу необхідно визначити параметри підключення до Вашого сервера БД - схема (база даних), логін і пароль.