Как сделать чтобы hibernate сам создавал таблицу

Добавил пользователь Alex
Обновлено: 19.09.2024

Итак, я все еще довольно новичок в Hibernate, и я работаю над широкоформатным приложением, которое уже имеет базу данных с несколькими таблицами Hibernate. Я работаю над новой функцией, которая включает новый класс @Entity , и мне нужны эти объекты, которые будут храниться в новой таблице. Класс объявляется следующим образом:

Таблица DATA_REQUEST не существует, и у меня нет никаких данных для ее хранения. Я начал приложение, ожидая, что он либо создаст таблицу, либо потерпит крах, потому что она еще не существует. Ничего из этого на самом деле не произошло.


В сегодняшней IT-индустрии хранение и извлечение данных приложений базируется на объектно-ориентированных языках программирования и реляционных базах данных. Базы данных хранят большой объем информации в одном месте. Наряду с этим, они предоставляют эффективный способ поиска записей, чтобы легко и быстро добраться до нужных данных.

Но при работе с объектами есть одна функция, которую база данных не поддерживает, — это хранение самих объектов, поскольку в ней хранятся только реляционные данные. Данные в виде объектов обеспечивают абстракцию и переносимость.

Существует ли метод, с п о мощью которого возможно напрямую хранить и извлекать объекты в реляционной базе данных? Ответ — да, такая возможность есть. Название этой техники — ORM.

ORM устраняет несоответствие между объектной моделью и реляционной базой данных. Само название предполагает отображение объектов в реляционные таблицы. Технология ORM преобразует объекты в реляционные данные и обратно. Возникает вопрос: как это делается?

По сути, имя переменной экземпляра присваивается имени столбца, а его значение формирует строку в реляционной базе данных. Теперь вопрос в том, нужно ли объявлять таблицу в базе данных для хранения объектов. Ответ — нет, ORM сделает это за нас, объявив типы данных для столбцов такими же, как и для переменных экземпляра.

Однако для этого нужно выполнить небольшую настройку и сообщить ORM, как будут отображаться объекты. В Java ORM работает с обычными старыми классами объектов Java (POJO), объекты которых необходимо сопоставить. Эти классы по сути состоят из частных переменных экземпляра, параметризованного конструктора с общедоступными геттерами и сеттерами.

Наряду с параметризованным конструктором класс POJO должен иметь открытый конструктор без аргументов, поскольку он необходим ORM для сериализации. Поскольку параметризованный конструктор присутствует, compile не будет добавлять конструктор аргументов самостоятельно, поэтому придется делать это вручную.

Hibernate — это высокопроизводительный инструмент объектно-реляционного сопоставления с открытым исходным кодом для языка программирования Java. Он был выпущен в 2001 году Гэвином Кингом и его коллегами из Cirrus Technologies в качестве альтернативы Entity Beans (объектным бинам) в стиле EJB2.

Этот фреймворк отвечает за решение проблем несоответствия объектно-реляционного импеданса. В Java есть спецификация под названием Java Persistence API (JPA), которая описывает управление объектами в реляционной базе данных. Hibernate — это всего лишь реализация JPA.

Обсудим компоненты, из которых состоит Hibernate. Hibernate имеет многоуровневую архитектуру и позволяет работать, даже не зная базовых API, реализующих объектно-реляционное сопоставление. Hibernate находится между Java-приложением и базой данных. Архитектура Hibernate подразделяется на четыре уровня:


  • уровень Java-приложения;
  • уровень фреймворка;
  • уровень API;
  • уровень базы данных.

На приведенной выше диаграмме показаны все четыре слоя. Поток данных между Java-приложением и базой данных выполняется с использованием постоянного объекта, определенного Hibernate. Уровень инфраструктуры Hibernate состоит из различных объектов, таких как конфигурация, фабрика сеансов, сеанс, транзакция, запрос и критерии. Эти объекты создаются вручную, по мере необходимости.

Объект конфигурации. Первый объект Hibernate, который должен присутствовать в любом Hibernate-приложении. Он активирует платформу Hibernate. Объект конфигурации создается только один раз во время инициализации приложения. Это родительский объект — именно из него создаются все остальные. Он проверяет, является ли файл конфигурации синтаксически правильным или нет. Он предоставляет свойства конфигурации и сопоставления, необходимые Hibernate.

Объект фабрики сеансов. Фабрика сеансов — это массивный потокобезопасный объект, используемый несколькими потоками одновременно. Таким образом, в приложении он должен быть создан только один раз и сохранен для последующего использования. Для каждой базы данных необходим отдельный объект фабрики сеансов. Фабрика сеансов отвечает за настройку Hibernate посредством свойств конфигурации, предоставляемых объектом конфигурации.

Объект сеанса. Облегченный объект, который создается каждый раз, когда нужно взаимодействовать с базой данных. Постоянные объекты сохраняются и извлекаются с помощью объекта сеанса. Это не потокобезопасный объект, поэтому его следует уничтожить после завершения взаимодействия.

Объект транзакции. Представляет собой единицу работы с базой данных. Это необязательный объект, но его следует использовать для обеспечения целостности данных и в случае возникновения какой-либо ошибки — выполнять откат.

Объект запроса. Объект запроса нужен для записи запросов и выполнения операций CRUD в базе данных. Можно написать запрос на SQL или воспользоваться языком запросов Hibernate (HQL). В процессе реализации вам станет известно о HQL больше.

Объект критериев. С его помощью выполняются объектно-ориентированные запросы для извлечения объектов из базы данных.

Во-первых, нужно установить Hibernate у себя в проекте. Можно загрузить jar-файл или воспользоваться более удобным способом, например, применить maven. Так и поступим. Загрузим зависимость hibernate, определенную в POM.xml.


Фреймворк Hibernate должен знать, как сопоставлять объекты, учетные данные сервера базы данных, где будут храниться и откуда будут извлекаться объекты, и еще несколько свойств. Вопрос в том, как передать всю эту информацию в Hibernate.

Эта настройка выполняется с помощью двух XML-файлов.

  • hibernate.cfg.xml содержит свойства гибернации, такие как диалект, класс драйвера, URL-адрес сервера базы данных, имя пользователя и пароль.
  • Файл сопоставления содержит взаимосвязь сопоставления между Java-объектами и таблицами базы данных. Имя файла должно соответствовать шаблону .hbm.XML. Например, если мы хотим работать с объектом типа “Employee”, имя файла будет Employee.hbm.xml.

XML-файлы необходимо поместить в папку META-INF внутри src/main/resources . Третий компонент, который понадобится в настройке, — это класс POJO, который мы обсуждали ранее.

Рассмотрим пример работы с объектом Flight. В качестве переменных экземпляра он содержит идентификатор (ID), номер рейса, место отправления, место прибытия, дату рейса и тариф. Идентификатор будет первичным ключом таблицы.


Приведенное выше изображение — это hbm.cfg.xml. Как видите, все свойства определены внутри тега hibernate-configuration . Внутри тега session-factory указываются свойства базы данных, к которой необходимо подключиться.

Свойство hbm2ddl.auto проверяет или экспортирует язык определения данных схемы при создании объекта фабрики сеансов. Здесь мы прописали операцию обновления, которая обновит базу данных, не затрагивая ранее записанные данные. Недостает еще нескольких, таких как проверка, создание и создание-удаление.


Приведенный выше XML-код относится к файлу сопоставления. Все свойства определены внутри тега hibernate-mapping . Тег class предназначен для определения имени класса POJO и имени таблицы, которые будут созданы внутри базы данных в качестве атрибутов, а отношения сопоставления — в качестве значений.

Первичный ключ определяется внутри тега id . Мы определяем имя переменной экземпляра внутри атрибута name . Имя столбца и тип данных указаны в атрибутах column и type соответственно. Теги generator предоставляют стратегию, с помощью которой необходимо выполнить автоинкремент. Все остальные сопоставления переменных экземпляра предоставляются внутри тегов свойств property .

Настало время, когда нужно создать класс POJO для рейсов ( Flights ), объекты которого будут сохраняться в таблице FLIGHTS. Здесь есть также пустой конструктор по умолчанию, необходимость которого мы обосновали ранее.


Один вопрос, который наверняка приходит вам в голову: если мы, Java-разработчики, пользуемся инструментарием Java, зачем выполнять настройку с использованием XML? Есть ли какой-нибудь другой способ? Ответ таков: да, но только частично.

От файла сопоставления можно избавиться с помощью аннотаций, но конфигурационный XML-файл все еще необходим. Аннотации — мощный способ определения взаимосвязи между объектом и реляционной моделью. Они начинаются с @ .

Нужно просто добавить аннотации внутри класса POJO. Отдельного файла не требуется:


Аннотацию необходимо указывать непосредственно над объявлением поля.

  • @Entity сообщает Hibernate, что этот класс — компонент сущности, и его объекты должны быть постоянными.
  • @Table применяется для указания имени создаваемой таблицы в базе данных.
  • @Id используется для определения первичного ключа. Можно также добавить совместно несколько полей, чтобы создать составной ключ.
  • @GeneratedValue определяет стратегию инкремента в поле. Это необязательный параметр — если он не определен с помощью @Id , применяется стратегия по умолчанию.
  • @Column определяет, как поле сопоставляется со столбцом в таблице. Аннотация принимает такие атрибуты, как имя столбца, определение столбца, возможность принимать null-значение, уникальность и т. д. В отличие от XML-файлов, здесь не нужно указывать тип, поскольку он берется непосредственно из поля.

Попробуем, наконец, выполнить CRUD-операции с помощью Hibernate. Для этого создадим класс с именем DAO . Но еще до этого нам понадобится объект фабрики сеансов. Есть два способа его создания. Если мы работаем без аннотации, то поступим вот так:


Другой способ будет определен в приведенном ниже примере. Процедура создания всех остальных объектов одинакова для обоих вариантов.

Первый пример — добавление объектов рейса Flight в базу данных. Создаем метод addFlight , который сохраняет объект в базе данных. Далее выполняется транзакция в режиме try-catch , чтобы в случае возникновения какой-либо проблемы удалось выполнить откат, а в противоположном случае — транзакция была зафиксирована в таблице.

Операция сохранения

Метод сохранения в объекте сеанса выполняет задачу вставки объекта.


Операция обновления

Теперь продвинемся вперед и попробуем обновить уже существующие в таблице данные.


Мы создали метод updateFlightNumber , в котором сначала извлекаем объект Flight с заданным идентификатором, а затем обновляем номер рейса методом-сеттером. После этого вызываем update -метод, чтобы обновить существующую сущность.

Примечание: если вам хочется вывести объекты, извлеченные из базы данных, на консоль, добавьте метод toString() в класс POJO, иначе выведется хэш-код.

Операция удаления

В базе данных есть только один объект с id=1 . Попытаемся удалить этот объект.


После выполнения метода deleteFlight таблица становится пустой. В приведенном выше коде мы сначала извлекли объект по его идентификатору и передали его методу удаления. Если все пойдет хорошо, транзакция окажется зафиксирована, в противном случае выполнится откат.

И еще одно: хотим ли мы обновить объект в базе данных или удалить его, нам понадобится значение его первичного ключа. Однако у нас не всегда есть возможность его получить. Кроме того, для этого необходимо выполнять сложные операции с данными. Цели можно достичь с помощью HQL, аналогичного SQL, но он удаляет шаблонный код. Это означает, что теперь не нужно использовать операторы select с запросами.


В данном уроке я продемонстрирую как работать с MySQL базой данных используя Maven 3 и Hibernate 3.2.

В этом уроке я кратко покажу вам, как использовать Maven для создания простого проекта Java с использованием Hibernate для работы с базой данных MySQL.

Что нам потребуется?

3) БД MySQL 5.5.30

4) Hibernate 4.1.11.Final

5) JDBC MySQL 5.1.24

Шаг 1. Создаем таблицу.

В вашей БД создадим таблицу user:

Шаг 2. Создание Maven проекта

В Intellij IDEA выбираем File->New Project->Maven module:


Шаг 3. Структура проекта

Создадим теперь класс EnterPoint.java который будет запускать наше приложение.

После чего структура проекта у вас должна выглядеть следующим образом:


Шаг 4. Добавляем зависимости

Теперь в pom.xml добавим зависимости для MySQL и Hibernate:

Шаг 5. Создаем Mapping файл

Создайте User.hbm.xml “src\main\resources\com\devcolibri\User.hbm.xml“:


Файл User.hbm.xml выглядит так:

Этот класс описывает таблицу, что в БД и сущность User.java, давайте её создадим.

catalog=’test’ – это имя БД.

table=’user’ – это имя таблицы на которую мы привязываем класс User.java.

Для этого создадим пакет entity (src\main\java\com\devcolibri\entity) и в нем создадим сущность User.java:package com.devcolibri.entity;

Это простой Java класс с атрибутами и Getter & Setter для них.

Шаг 6. Создание конфигурационного файла Hibernate

Создадим конфигурационный файл для Hibernete hibernate.cfg.xml по пути “src\main\resources\hibernate.cfg.xml” со следующим содержимым:

Этот файл отвечает за соединение с БД и связкой наших mapping с ней.

Строка 8 говорит о том что для роботы с БД мы используем JDBC MySQL драйвер.

Строка 9 – пароль к БД.

Строка 10 – host к БД, где test – база данных.

Строка 11 – логин вашего пользователя к БД.

Строка 15 – замапенный класс User, что бы hibernate знал за какую таблицу в БД отвечает этот класс.

Шаг 7. Создание Hibernate Utility класса

Этот класс будет заботится о начале сессии.

Создадим класс HibernateUtil.java тут “src\main\java\com\devcolibri\persistence\HibernateUtil.java” со следующим содержанием:

Шаг 8. Финишная структура проекта

Теперь проверим структуру проекта, она должна совпадать с этой:


Шаг 9. Сохранение user в БД

Теперь в класс EnterPoint.java допишем следующий код:

Шаг 10. Запуск

Запускаем EnterPoint.java и в консоли будут выведены логи Hibernate и такая строчка:

это значит что запись успешно добавлена.

Идем в БД и смотрим действительно ли добавлена запись в БД.


p.s. Спасибо за внимание! Если вам урок понравился, то подписывайтесь на обновление в форме ниже.

ПОХОЖИЕ ПУБЛИКАЦИИ

34 комментариев к статье "Как работать с MySQL в Java - Hibernate XML Mapping"

Вообще то хибернейт сам создает в БД Таблицу, по полям которые прописаны в модели… Да и к сожалению слишком много кода, сейчас все активно переходят на Аннотации, и еще Чисто хибернейт использовать не нужно лучше всего через интерфейс JPA. тогда код будет лаконичный. Для новичков это будет страшно видеть…

Не умея юзать Hibernate юзать JPA с использование Hibernate provider? Думаю вы не совсем понимаете суть. И на сайте есть статья по поводу JPA и Hibernate в качестве провайдера.

Я тренируюсь использовать JPA, для понимания работы сущностей, аннотаций, менеджера сущностей описываю достаточно сложные или новые сущности. Чтобы использовать EntityManager у меня должны быть созданы таблицы. Руками через SQL со всеми зависимостями их не очень легко создавать. Я знаю, что можно настроить hibernate что бы он сам создавал таблицы на основе сущностей. Я искал в интернете, на киберфоруме, на стэковерлоф, на туториалах от хибернейта, но все равно не понял до конца как это сделать. Единственное, что я понял - что в persistence.xml надо указать строку

. Я указал, но ничего не происходит при запуске хибернейта, таблиц не появляются в бд. Что мне сделать, что бы у меня создались таблицы на основе сущностей которые я описал? Может кто то пошагово описать все шаги которые я должен сделать чтобы получить бд на основе сущности?

В первой зависимости мы подключаем hibernate - core набор минимальных библиотек для работы с hibernate . Во второй и третьей зависимости мы подключаем логирование для ведения лога отладки, который поможет нам понять, что же твориться внутри hibernate . В четвертой зависимости мы загружаем библиотеку базы данных H 2, которая полностью написана на java и которая на первом этапе поможет нам избежать ненужной настройки и установки базы данных, такой как mysql или postgresql на пример. Перейдите в каталог code\c2\src\main\resources , вы тут найдите файл hibernate.cfg.xml. Это основной конфигурационный файл Hibernate хранящий настройки, давайте перечислим самые часто используемые из них:

Диалект базы данных, который будет использоваться hibernate , вы наверное знаете что есть международные стандарты sql языка, но у каждой базы данных своя реализация, и соответственно некоторые стандарты могут быть не реализованы, или реализованы частично, или специфически. Вот что бы предусмотреть нестандартные, специфические команды sql конкретной базы данных и ввели в hibernate диалект. Перечислю несколько из них: H 2 Dialect , MySQL5Dialect, Oracle10gDialect, PostgreSQL81Dialect. Полный список диалектов вы можете найти в пакете org.hibernate.dialect.*

При разработке и тестировании приложения, всегда бывает полезно, знать какие действия выполняет Hibernate . Включает логирование действий Hibernate , очень полезная вещь, всегда советую включать при разработке приложения.

Размер выборки данных из результирующего набора данных JDBC . Допустим, hibernate отправил sql запрос на выборку данных и в него, попало 100 записей. Размер выборки 20. Hibernate потребуется 5 раз сделать выборку из результирующего набора JDBC .

Устанавливает глубину выборки зависимых классов, т.е. сколько зависимых классов будет заполнено данными. Этот параметр может помочь избежать ненужной выборки данных для классов, и выполнения излишних sql запросов к базе данных, так как иногда бывает, не известно нужна ли будет информация по зависимым классам, или нет.

В файле log4j.properties находятся настройки для логирования проекта в целом и в частности Hibernate . Давайте создадим класс Person , который будет отображать одну запись из таблицы Persons в базе данных H 2. Таблица Persons будет содержать уникальный ключ personId, имя – fName и фамилию – sName. Нам нужно как-то сопоставить таблицу Persons и поля таблицы, с классом Person и полями класса, в этом нам помогут аннотации. Давайте взглянем на класс Person . java :

if (firstName != null ? !firstName.equals(person.firstName) : person.firstName != null) return false;

if (secondName != null ? !secondName.equals(person.secondName) : person.secondName != null) return false;

Класс Person представляет собой POJO класс, отображение таблицы на класс называется сущностью. Сущность можно реализовать двумя способами. Первый способ это сначала отдельно создать таблицу Persons и связать ее с POJO классом Person . java . И второй способ это создать сначала POJO класс Person и включить в конфигурационном файле hibernate.cfg.xml параметр hbm2ddl.auto, который попросит Hibernate сгенерировать схемы таблиц базы данных на основе POJO класса. Пойдем наипростейшим путем, выберем второй способ и поставим значение в свойстве hbm2ddl.auto равным create, которое будет постоянно требовать, пересоздавать, пустую таблицу Persons при каждом запуске нашей программы. При окончательном развертывании приложения в продуктивной среде, я бы вам советовал все ключи, индексы, триггеры, перечисления именовать вручную с подходящими по смыслу именами. И к ним же добавить все схемы таблиц баз данных т.е. прописать в отдельном sql файле весь сценарий создания базы данных. Продолжим, и так что бы наш класс Person правильно взаимодействовал с hibernate и стал сущностью, нужно, во-первых применить к нему аннотации и второе POJO объект должен удовлетворять следующим требованиям:

3. Иметь поле "первичного ключа" (id) как минимум, как максимум сложный составной ключ, это условие не обязательно, сущность может и не иметь ключа, но это чревато большими проблемами.

Немножко отступим от темы и поговорим о интерфейсе Serializable. С каждым сериализуемым классом связан уникальный идентификационный номер serialVersionUID. Если вы не указываете этот идентификатор явно, декларируя поле private static final long с названием serialVersionUID, система генерирует его автоматически, используя для класса сложную схему расчетов. При этом на автоматически генерируемое значение оказывают влияние название класса, названия реализуемых им интерфейсов, а также все открытые и защищенные члены. Если вы каким-то образом поменяете что-либо в этом наборе, например, добавите новый метод, изменится и автоматически генерируемый serial versionUID. Следовательно, если вы не будете явным образом декларировать этот идентификатор, совместимость с предыдущими версиями будет потеряна. Клиенты, которые пытаются сериализовать объект с помощью старой версии класса и десериализовать его уже с помощью новой версии, получат сбой программы. И так, как создать static final long s erialVersionUID? Пусть у нас есть скомпилированный класс src / org / vit / Person . class

Читайте также: