Hibernate: ще раз про hibernate або getting started
Hibernate - це технологія, що дозволяє працювати з сутностями в базі даних так, як ніби вони локальні об'єкти, по-іншому - ORM (Object-relational mapping), зв'язування бази даних з об'єктами, створення «віртуальної об'єктної бази даних».
Наприклад, в hibernate рядок коду
Чи збереже книгу в базу даних. Зручно? Досить зручно, щоб витратити деякий час для вивчення цієї технології.
Отже, під катом ще одне виклад із серії «Hibernate: getting started» і повністю працюючий приклад.
приготувалися
Сам hibernate можна скачати на офіційному сайті, проте не всі необхідні бібліотеки для роботи з ним поставляються в комплекті. Але все ж рекомендую скачати його, тому що там знаходиться документація, та й до того часу цілком може вийти нова версія.
Для початку коротко розкажу про те, як це працює. У програмі ми створюємо класи для їх зв'язування з сутностями нашої бази даних. В англійській літературі такі класи ще називають pojo - plain old java odjects. У них містяться набір приватних полів, для кожного з них є геттер і сетер, конструктор за замовчуванням (який без параметрів), а так само будь-які інші конструктори за бажанням. Зазвичай цього достатньо для таких класів.
Зв'язування класів java з таблицями в базі даних відбувається за допомогою спеціального маппинг-файлу, в якому вказується, яких полях класу які стовпці відповідають в базі.
При першому зверненні до hibernate, він зчитує всі параметри з файлу hibernate.cfg.xml. в якому зберігається рядок підключення до БД, логін / пароль, вказуються шляхи до маппинг-файлів.
Далі реалізуються функції, відповідні бізнес-логікою програми, але на їх реалізацію йде куди менше часу в порівнянні з традиційним JDBC - адже все взаємодії програміста зводиться до роботи з «локальними» об'єктами і періодичному їх збереженню.
Ну що ж, приступимо
В якості СУБД я використовую MySQL.
Тепер приступимо до створення класів java - таких же сутностей, з такими ж зв'язками, як у нашій базі. Це будуть класи Book, Author, Reader і Using. Вони будуть мати приховані поля, кожна з сутностей саме такі, якими ми їх створили в нашій базі, набір геттеров і сеттерів, і набір конструкторів (можна один конструктор за замовчуванням, що не приймає ніяких аргументів).
Частково приведу ці класи:
Асоціюємо класи з базою
Тепер прийшов час повідомити hibernate про те, що ці класи є об'єктним відображенням сутностей з бази даних. Для цього використовуються спеціальні mapping-файли, що представляють собою xml-файл з набором інструкцій.
Інструкції міститися в тегах
вказує, яке ключове поле треба використовувати для зв'язку;
вказує кратність відносин між цією сутністю і інший, в даному прикладі це - багато-до-багатьох.
Кожен з цих тегів має свій набір параметрів, розглядати які найкраще на прикладі:
У кожному полі є тег
вказує, з якою колонкою в таблиці бази даних слід пов'язати це властивість;
Наведу цілком файли, в яких описуються ці зв'язки:
Ще є зв'язок one-to-one, але з огляду на те, що вона майже не використовується, я опущу її розгляд.
Так само звертаю увагу на те, що при реалізації зв'язку багато-до-багатьох опція зі зв'язком вказує на проміжну таблицю AUTHORSBOOKS. а не на AUTHORS.
Але не обов'язково все це писати руками - все вже зроблено за нас. Якщо ви встановили плагін для Екліпс, то можна створити ці файли кодогенератор, клацнувши на пакеті з потрібними об'єктами на праву кнопку миші, вибравши new -> other ... і в списку з hibernate вибравши «hibernate mapping file». Відзначаємо галочками потрібні класи для генерації і дивимося результат.
По-друге, ми використовуємо автоінкрементіруемое ключове поле, а не вказуємо його самі, тому в параметрі всюди змінюємо assigned на native.
По-третє, він не створює зв'язку багато-до-багатьох, тому правимо результат ручками.
налаштовуємо
Тепер треба налаштувати сам hibernate, вказати йому, яку базу ми використовуємо, які файли карт потрібно підключати.
Ось вийшов у мене файл настройок, думаю в ньому і так все зрозуміло. Спочатку йдуть настройки підключення, потім вказуємо шлях до файлів з картами. Опцію з кодуванням потрібно вказати, якщо в проекті використовується кирилиця, інакше всі російські символи дійдуть до MySQL як купа знаків питання.
Якщо встановити значення властивості show_sql в true, то він буде видавати в stdout все згенеровані ним запити. Щоб поспостерігати, як він працює, краще залишити в true.
Цей файл потрібно покласти в кореневій каталог для всіх вихідних файлів, в разі проекту в Екліпс - це папка src /. Туди кладемо його, називаємо hibernate.cfg.xml.
Тепер створюємо спеціальний менеджер сесій для роботи з хибернейт. Створимо для нього окремий пакет, в ньому клас і напишемо:
При виклику методу getSessionFactory () відбудеться ініціалізація хибернейт, він прочитає всі настройки, зв'яже об'єкти з таблицями в базі даних.
програмуємо
Отже, визначимо, які методи нам можуть стати в нагоді для роботи з записами в базі. наприклад:
- додавання;
- видалення;
- зміна;
- отримання всього списку;
- отримання елемента по id;
Створимо інтерфейс, що описує ці функції. Інтерфейс створимо узагальнений:
Реалізуємо цей інтерфейс.
Повністю тут приводити його не буду, зацікавлені можуть завантажити прикладений исходник і покопатися в ньому. Розповім лише, що для взаємодії з БД використовуються наступні методи класу Session:
session.save (el); - зберегти елемент в БД;
session.update (el); - оновити елемент;
session.delete (el); - видалити;
session.saveOrUpdate (el); - зберегти або відновити;
el = (E) session.get (elementClass, elId); - отримати елемент по id;
els = session.createCriteria (elementClass) .list (); - список всіх елементів.
При реалізації цього інтерфейсу я застосував деяку хитрість - зверніть увагу на конструктор. Отримання класу (об'єкта типу Class за допомогою рядка типу E.class) в java неможливо, але взаємодія з базою в Хібернія відбувається саме за допомогою класів - в критерії вказується, який клас потрібно отримати. Тому був створений конструктор, що приймає об'єкт типу Class в якості параметра. Зауважу, що клас ElementDAOImpl не призначений для прямого використання, а повинен успадковуватися і явно визначати тип елемента. наприклад:
Таким чином я реалізував і всі інші класи.
Тепер створимо клас-одиночку, що надає можливість безпосереднього маніпулювання з даними:
Тепер можна працювати з базою:
Однак цей набір функцій - зовсім не те, чого б нам хотілося. Вірніше, то, але тільки зовсім небагато. Тому мають бути реалізовані функції, що відповідають заданій бізнес-логікою програми. наприклад:
- додати ряд книг з текстового файлу;
- дати книгу;
- прийняти книгу;
- знайти всі книги, які коли-небудь брав читач;
- знайти всі прострочені книги;
У hibernate існує три способи формування формування вибірки з бази даних.
- За допомогою мови запиту HQL;
- За допомогою Criteria API;
- За допомогою звичайного SQL.
Розглянемо окремо кожен з варіантів.
HQL дуже схожий на звичайний SQL, основна відмінність в ньому, що запит формується, як до об'єкта. Краще наведу пару прикладів:
Ще цікавий приклад, в якому в результаті виконання запиту створюється об'єкт:
Природно, у об'єкта повинен бути такий конструктор, інакше hibernate вилається, сказавши, що відповідного конструктора, не знайдено. Така собі суміш sql і java виходить.
Так, забув сказати, що параметри в запит підставляються за допомогою виклику функції