Pull to refresh

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

Level of difficultyEasy

Наверное трудно найти программиста, а тем более 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. Сформулировать правильные вопросы к "старшим" товарищам или к Гуглу.

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

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.