Как стать автором
Обновить

HIBERNATE (что может быть проще !?)

Уровень сложностиПростой

Наверное трудно найти программиста, а тем более Java-программиста, который бы никогда не слышал о hibernate. Если вы инженер с опытом - статья может показаться вам глупой, бесполезной, но она ориентирована на тех, кто уже слышал о hibernate, но никогда не трогал его руками. Что могу сказать - пришло время потрогать.

На всякий случай, очень коротко о том, что это такое и зачем hibernate нужен. Итак, hibernate - это библиотека для Java, которая позволяет работать с таблицами БД, как обычными Java-обьектами. То есть не нужно писать SQL-запросы - hibernate все сделает за вас. Кому такого описания мало - милости прошу на официальный https://hibernate.org/. Там вам представится возможность убить пару недель свободного времени. В большинстве случаев официальная документация становится помощником только тогда, когда ты знаешь, что ты хочешь спросить. Эта статья скорее quickstart.

Основная проблема большинства фреймворков, и основная причина почему хочется постоянно отложить на потом их изучение - это некий набор действий, который надо выполнить ДО того, как будет написана первая строчка кода, реализующего логику приложения. Иногда достаточно просто подключить в pom.xml какую-нибудь зависимость, а иногда прямо надо серьезно заморочиться. Увы, с hibernate такая же ситуация.

Что нам потребуется (в скобочках я буду указывать версии):

  • JDK (java version "21.0.2" 2024-01-16 LTS)

  • IDE (Idea 2023.1 Community Edition)

  • СУБД (PostgresSQL 16)

  • GUI для DB (pgAdmin4)

Предполагается, что все это счастье установлено на локальном хосте, настроено и проверено. В принципе СУБД может быть установлена, где угодно, но тогда заранее надо проверить, что связь с нею есть, и права у вашего пользователя на конкретную базу в наличии.

Создаем проект

Будем работать с проектом на maven, который идея создаст по умолчанию.

После того как дефолтовый проект создан, идем в папочку ˜Sources/hibernate_quick_start/src/main/resources, где создаем файл конфигурации hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<!-- Database connection properties -->
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
<property name="hibernate.connection.url">jdbc:postgresql://localhost:5433/examples</property>
<property name="hibernate.connection.username">postgres</property>
<property name="hibernate.connection.password">password</property>

<!-- Other Hibernate properties -->
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>

<!-- first time it is create and then onwards update -->
<property name="hbm2ddl.auto">update</property>

<!-- Mapping files or annotated classes -->
<!-- Add your entity classes or mapping files here for ex: entity used below -->
<mapping class="dev.engel.example.Worker"/>

</session-factory>
</hibernate-configuration>

Этот файл можно использовать как есть, кроме свойств с именем hibernate.connection.*. Думаю тут очевидно - если у ваc не postgres - указываете свое, адрес, порт и database тоже свои. Ну и креды пользователя, с которыми вы будете ходить в базу, разумеется свои. Также обратите внимание на строчку

<mapping class="dev.engel.example.Worker"/>

Это собственно и есть класс, который hibernate свяжет с конкретной таблицей в базе данных. Создаем этот файл. Создать его можно где угодно, но потом его полное имя надо занести сюда.

Создаем класс dev.engel.example.Worker

package dev.engel.example;

import jakarta.persistence.*;

@Entity
@Table(name = "workers")

public class Worker {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;

@Column(name = "FirstName") private String FirstName;

@Column(name = "SecondName") private String SecondName;

// Getters and setters, constructors, etc.

public Long getId() { return id; }

public void setId(Long id) { this.id = id; }

public String getFirstName() { return FirstName; }

public void setFirstName(String FirstName) { this.FirstName = FirstName; }

public String getSecondName() { return SecondName; }

public void setSecondName(String SecondName) { this.SecondName = SecondName; }
}

Немного пояснений. Для того, чтобы hibernate смог связать класс с таблицей БД, необходимо, чтобы были

  1. @Entity - аннотация поясняющая, что эта сущность будет связываться таблицей БД

  2. @Table - аннотация описывающая с какой именно таблицей БД этот класс будет ассоциирован. Если у аннотации нет параметров вообще - значит имя таблицы будет предполагаться равным имени класса. Иначе - то, что указано в параметрах

  3. Как минимум одно поле с аннотацией @Id

  4. Как минимум одно поле с аннотацией @Column - в параметрах указывается точное название поля БД

Разумеется, все это счастье обкладываем геттерами и сеттерами - для удобства. На этом минимальная подготовка окружения закончена.

Что теперь с этим делать

У нас по дефолту создается класс Main. Давайте поиспользуем его:

  1. Создаем метод getRows()

  2. Вызываем его и main()

public static void main(String[] args) { getRows();
}

public static void getRows() {
SessionFactory sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
Session session = sessionFactory.openSession();
session.getTransaction().begin();
List<Worker> employees = session.createQuery("FROM Worker", Worker.class).getResultList();
for (Worker employee : employees) {
System.out.println(
"ID: " + employee.getId() +
", FirstName: " + employee.getFirstName() +
", SecondName: " + employee.getSecondName());
}
session.getTransaction().commit();
session.close();
sessionFactory.close();
}

Запускаем и смотрим что получилось:

Hibernate:
select
w1_0.id,
w1_0.FirstName,
w1_0.SecondName
from
workers w1_0

В логе мы увидим команду, которую выполнил hibernate. И выполнил успешно. Тут наиболее внимательные заметят - ведь такую таблицу мы не создавали, а тут никакой ошибки. Возвращаемся к конфигурационному файлу, и смотрим на строку


<!-- first time it is create and then onwards update --> <property name="hbm2ddl.auto">update</property>

Она означает, что если вдруг на момент обращения к указанной таблице ее не существует - она будет создана. Если такое поведение системы вас не устраивает - удалите указанную строку и при отсутствии нужной таблицы программа будет падать.

Кстати, неспроста в коде есть вывод результата запроса. При первом запуске в результате ничего не пришло (создалась только пустая таблица), поэтому и вывода никакого.

Добавим метод:

public static void addRow() { SessionFactory sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
Session session = sessionFactory.openSession();
Worker e0 = new Worker();
e0.setId(0L);
e0.setFirstName("Иванов");
e0.setSecondName("Иван");
Worker e1 = new Worker();
e1.setId(1L);
e1.setFirstName("Петров");
e1.setSecondName("Петр");
Worker e2 = new Worker();
e2.setId(2L);
e2.setFirstName("Сидоров");
e2.setSecondName("Сидор");

session.getTransaction().begin();
session.save(e0);
session.save(e1);
session.save(e2);
session.getTransaction().commit();

session.close();
sessionFactory.close();
}

... и вызовем его из main().

Теперь в логе видим другие запросы, которые выполнил hibernate

Hibernate:
insert
into
workers
(FirstName, SecondName)
values
(?, ?)
Hibernate:
insert
into
workers
(FirstName, SecondName)
values
(?, ?)
Hibernate:
insert
into
workers
(FirstName, SecondName)
values
(?, ?)

Теперь повторим вызом метода getRows()

Hibernate:
select
w1_0.id,
w1_0.FirstName,
w1_0.SecondName
from
workers w1_0
ID: 1, FirstName: Иванов, SecondName: Иван
ID: 2, FirstName: Петров, SecondName: Петр
ID: 3, FirstName: Сидоров, SecondName: Сидор

Мы снова видим запрос, который выполнил hibernate, но в этот раз он уже вернулся не пустым. Результат содержит то, что мы записали в таблицу.

У меня не было цели описать все, что можно сделать с помощью hibernate - но работая с этим примером начинающий разработчик сможет

  1. Понять о чем это вообще

  2. На простом примере попробовать подергать БД

  3. Сформулировать правильные вопросы к "старшим" товарищам или к Гуглу.

Желаю всем успехов в постижении этого ремесла.

Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.