Object Relational Mapping

Модуль 4. Работа с БД
9 уровень , 0 лекция
Открыта

1.1 Маппинг классов на таблицы

После изучения JDBC у тебя скорее всего сложилось мнение, что работать с базой данных из Java-приложения — то еще удовольствие. А что если я скажу, что всю это работу можно сделать в 10 раз проще?

В чем главное преимущество языка SQL? Это декларативный язык — он описывает, что мы хотим получить, и совсем ничего не говорит о том, как это сделать. Как — это уже забота SQL-сервера.

Тот же подход можно использовать и при работе с базами данных.

В идеальном мире мы могли бы просто писать SQL-запросы к базе, а в ответ нам бы приходили готовые Java-объекты, ну или коллекции Java-объектов, если мы запросили несколько штук.

Что сказать, именно так подумали несколько ребят в 2000 году и решили написать свой ORM framework.

ORM расшифровывается как Object-Relational Mapping и по сути является маппингом Java-объектов на SQL-запросы.

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

Было три подхода к решению этой задачи, и выглядели они примерно так:

  1. Объект сам себя сохраняет в базу данных и обновляет свои поля на основе информации из БД.
  2. Объект умеет сохранять себя в базу данных, но никогда не выступает инициатором этого дела.
  3. Объект содержит только данные, и кто-то его сохраняет в базу данных и загружает из БД.

Изначально доминировал первый подход, тогда были популярны Application-сервера и Enterprise Java Beans. Был даже целый класс бинов, которые назывались Persistence EJB, которые умели себя сохранять в базу сами.

Но однажды все изменилось…

1.2 Появление Hibernate

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

Маппинг полей Java-классов и колонок в таблице в базе задавался с помощью XML-файла. И иногда они были довольно громоздкими. Ладно, кого я обманываю. Это были здоровенные полотна XML-кода. И ситуацию спасало только то, что 20 лет назад не было таких гигантских баз данных, как сейчас.

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

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

Серьезный прорыв случился после выхода Java 5, когда в JDK появились две вещи:

  • Аннотации
  • Proxy

Аннотации быстро вытеснили XML, и теперь прямо в Java-классе можно было легко указать все нужные настройки для маппинга Java-класса на таблицу в базе данных.

Прокси не так заметны для пользователя Hibernate, но их вклад был еще серьезнее. Когда ты запрашиваешь определённый объект или объекты у Hibernate, он просто возвращает тебе заглушку (proxy), и перехватывает все обращения к ее методам.

Это позволило реализовать различные механизмы Lazy Loading’а и подняло скорость и эффективность работы Hibernate на совсем заоблачный уровень для того времени. Hibernate стал не просто стандартом отрасли де-факто — его начали переводить на другие языки. Так, например для C# появился Framework NHibernate.

1.3 Появление JPA

За де-факто пришло и признание де-юре. Разработчики JDK решили создать спецификацию по тому, как правильно мапить объекты на таблицы в базе данных. Эта спецификация называется JPA — Java Persistence API.

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

Такое ощущение, что ребята просто взяли за основу Hibernate и поменяли у него имена пакетов. Потому что все аннотации, которые были в Hibernate, почти один в один переехали в JPA.

На сегодняшний день Hibernate полностью реализует всю спецификацию JPA, а также некоторые дополнительные возможности, которые делают работу с ним еще комфортнее. Поэтому с точки зрения стандартизации можно сказать, что у Hibernate есть два набора функций:

  • JPA-стандарт
  • Hibernate Native API (дополнительная функциональность)

В официальной документации Hibernate это описывается так:

Но и на основе своего опыта, и после повторного прочтения документации по Hibernate я могу сказать, что JPA и Hibernate API совпадают на 95%. Это просто тождественные понятия.

1.4 Maven для Hibernate

Раз уж я так сильно расхвалил Hibernate, думаю, настало время перейти к работе с ним немного поплотнее.

Во-первых, есть официальный сайт, где просто куча англоязычной документации. Она, конечно, имеет уклон в справочную информацию, а не в обучающую. Но все равно лучше так, чем дебажить исходники, верно? :)

Инструкция:

  1. Открываешь ссылку.
  2. Долго на нее смотришь.
  3. Возвращаешься на JavaRush.
  4. Читаешь мои дальнейшие лекции.

Моя работа и состоит в том, чтобы упрощать сложные вещи и объяснять их простыми словами. И если ты дошел до этого уровня, значит, у меня это получается.

Ну, а чтобы приступить к работе с Hibernate, тебе нужно добавить его в свой pom.xml. На сегодняшний день доступна уже 6-я версия Hibernate, а точнее 6.1.1, так что будем учиться работать с самой последней версией.

Просто добавь в свой pom.xml такие строки:


<dependency>
	<groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
	<version>6.1.1.Final</version>
</dependency>

Если ты читаешь эту лекцию и за окном 2023+ год, тогда новую версию можно скачать тут.

Важно! Некоторые библиотеки, которые использует Hibernate, были исключены из JDK 11 и JDK 17, поэтому если у тебя возникают проблемы с запуском проекта, то добавь в него такие зависимости:


  	<dependency>
        <groupId>jakarta.xml.bind</groupId>
        <artifactId>jakarta.xml.bind-api</artifactId>
      	<version>4.0.0</version>
  	</dependency>
 
  	<dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
      	<version>4.0.0</version>
  	</dependency>
 
  	<dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.29.0-GA</version>
  	</dependency>

Комментарии (8)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
nastya_zhadan Уровень 66
7 октября 2025
Актуальная ссылка на Hibernate
СтудентJava Уровень 109
2 февраля 2025
Вот и дошел до Hibernate. Столько о нем слышал☺️
Антон Уровень 115
28 января 2025

Моя работа и состоит в том, чтобы упрощать сложные вещи и объяснять
их простыми словами. И если ты дошел до этого уровня, значит, у меня
это получается.
Не благодаря, а вопреки 😏
Роман Уровень 88
7 января 2025
прям добротная лекция
Павел Уровень 19 Expert
11 марта 2024
По английски пишу плохо поэтому только так
Daniel Уровень 51
26 июля 2023

Но однажды все изменилось…
Когда народ огня развязал войну :)
Ruslan Shamsiev Уровень 1
25 января 2023
Hibernate ORM enables developers to more easily write applications whose data outlives the application process. As an Object/Relational Mapping (ORM) framework, Hibernate is concerned with data persistence as it applies to relational databases (via JDBC).
Sanjay-linux Уровень 1
11 октября 2022
ORM support is provided in java or spring via JPA . In JPA, the EntityManager interface is used to allow applications to manage and search for entities in the relational database. The EntityManager is an API that manages the lifecycle of entity instances. An EntityManager object manages a set of entities that are defined by a persistence unit.