Учебники

Hibernate — Краткое руководство

Hibernate — Обзор ORM

JDBC расшифровывается как Java Database Connectivity . Он предоставляет набор API Java для доступа к реляционным базам данных из программы Java. Эти API Java позволяют программам Java выполнять операторы SQL и взаимодействовать с любой базой данных, совместимой с SQL.

JDBC предоставляет гибкую архитектуру для написания независимого от базы данных приложения, которое может работать на разных платформах и взаимодействовать с разными СУБД без каких-либо изменений.

Плюсы и минусы JDBC

Плюсы JDBC Минусы JDBC

Чистая и простая обработка SQL

Хорошая производительность с большими данными

Очень хорошо для небольших приложений

Простой синтаксис так легко выучить

Сложный, если он используется в крупных проектах

Большие накладные расходы на программирование

Нет инкапсуляции

Трудно реализовать концепцию MVC

Запрос специфичен для СУБД

Чистая и простая обработка SQL

Хорошая производительность с большими данными

Очень хорошо для небольших приложений

Простой синтаксис так легко выучить

Сложный, если он используется в крупных проектах

Большие накладные расходы на программирование

Нет инкапсуляции

Трудно реализовать концепцию MVC

Запрос специфичен для СУБД

Почему объектно-реляционное сопоставление (ORM)?

Когда мы работаем с объектно-ориентированной системой, существует несоответствие между объектной моделью и реляционной базой данных. СУБД представляют данные в табличном формате, тогда как объектно-ориентированные языки, такие как Java или C #, представляют их как взаимосвязанный граф объектов.

Рассмотрим следующий Java-класс с правильными конструкторами и связанной с ним публичной функцией —

public class Employee {
   private int id;
   private String first_name; 
   private String last_name;   
   private int salary;  

   public Employee() {}
   public Employee(String fname, String lname, int salary) {
      this.first_name = fname;
      this.last_name = lname;
      this.salary = salary;
   }
   
   public int getId() {
      return id;
   }
   
   public String getFirstName() {
      return first_name;
   }
   
   public String getLastName() {
      return last_name;
   }
   
   public int getSalary() {
      return salary;
   }
}

Учтите, что вышеперечисленные объекты должны быть сохранены и извлечены в следующую таблицу RDBMS:

create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

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

Sr.No. Несоответствие и описание
1

Зернистость

Иногда у вас будет объектная модель, которая имеет больше классов, чем количество соответствующих таблиц в базе данных.

2

наследование

СУБД не определяют ничего похожего на Inheritance, которая является естественной парадигмой в объектно-ориентированных языках программирования.

3

тождественность

СУБД определяет ровно одно понятие «сходство»: первичный ключ. Java, однако, определяет как идентичность объекта (a == b), так и равенство объектов (a.equals (b)).

4

ассоциации

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

5

навигация

Способы доступа к объектам в Java и в RDBMS принципиально различны.

Зернистость

Иногда у вас будет объектная модель, которая имеет больше классов, чем количество соответствующих таблиц в базе данных.

наследование

СУБД не определяют ничего похожего на Inheritance, которая является естественной парадигмой в объектно-ориентированных языках программирования.

тождественность

СУБД определяет ровно одно понятие «сходство»: первичный ключ. Java, однако, определяет как идентичность объекта (a == b), так и равенство объектов (a.equals (b)).

ассоциации

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

навигация

Способы доступа к объектам в Java и в RDBMS принципиально различны.

Приложение O bject- R elational M (ORM) — это решение для обработки всех вышеуказанных несовпадений импеданса.

Что такое ORM?

ORM расшифровывается как O bject- R elational M apping (ORM) — это метод программирования для преобразования данных между реляционными базами данных и объектно-ориентированными языками программирования, такими как Java, C # и т. Д.

Система ORM имеет следующие преимущества перед простым JDBC:

Sr.No. преимущества
1 Давайте бизнес-кодам обращаться к объектам, а не к таблицам БД.
2 Скрывает детали SQL-запросов от ОО-логики.
3 По материалам JDBC «под капотом».
4 Не нужно заниматься реализацией базы данных.
5 Объекты, основанные на бизнес-концепциях, а не на структуре базы данных.
6 Управление транзакциями и автоматическая генерация ключей.
7 Быстрая разработка приложения.

Решение ORM состоит из следующих четырех объектов:

Sr.No. Решения
1 API для выполнения основных операций CRUD над объектами постоянных классов.
2 Язык или API для указания запросов, которые ссылаются на классы и свойства классов.
3 Настраиваемое средство для указания метаданных отображения.
4 Техника взаимодействия с транзакционными объектами для выполнения грязной проверки, отложенной выборки ассоциаций и других функций оптимизации.

Java ORM Frameworks

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

  • Enterprise JavaBeans Entity Beans
  • Объекты данных Java
  • колесико
  • TopLink
  • Весна ДАО
  • зимовать
  • И многое другое

Hibernate — Обзор

Hibernate — это решение O bject- R elational M (ORM) для JAVA. Это постоянный фреймворк с открытым исходным кодом, созданный Гэвином Кингом в 2001 году. Это мощный высокопроизводительный сервис объектно-реляционной персистентности и запросов для любого Java-приложения.

Hibernate отображает классы Java в таблицы базы данных и из типов данных Java в типы данных SQL и освобождает разработчика от 95% общих задач программирования, связанных с сохранением данных.

Hibernate находится между традиционными объектами Java и сервером базы данных и выполняет все действия по сохранению этих объектов на основе соответствующих механизмов и шаблонов O / R.

Положение гибернации

Преимущества гибернации

  • Hibernate занимается отображением классов Java в таблицы базы данных с использованием файлов XML и без написания какой-либо строки кода.

  • Предоставляет простые API-интерфейсы для хранения и извлечения объектов Java непосредственно в базу данных и из нее.

  • Если в базе данных или в любой таблице произошли изменения, вам нужно изменить только свойства XML-файла.

  • Абстрагирует незнакомые типы SQL и предоставляет способ работы со знакомыми объектами Java.

  • Hibernate не требует сервера приложений для работы.

  • Управляет сложными ассоциациями объектов вашей базы данных.

  • Минимизирует доступ к базе данных с помощью умных стратегий извлечения.

  • Обеспечивает простой запрос данных.

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

Предоставляет простые API-интерфейсы для хранения и извлечения объектов Java непосредственно в базу данных и из нее.

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

Абстрагирует незнакомые типы SQL и предоставляет способ работы со знакомыми объектами Java.

Hibernate не требует сервера приложений для работы.

Управляет сложными ассоциациями объектов вашей базы данных.

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

Обеспечивает простой запрос данных.

Поддерживаемые базы данных

Hibernate поддерживает практически все основные СУБД. Ниже приведен список нескольких ядер баз данных, поддерживаемых Hibernate.

  • HSQL Database Engine
  • DB2 / NT
  • MySQL
  • PostgreSQL
  • FrontBase
  • оракул
  • База данных Microsoft SQL Server
  • Sybase SQL Server
  • Informix Dynamic Server

Поддерживаемые технологии

Hibernate поддерживает множество других технологий, в том числе —

  • XDoclet Spring
  • J2EE
  • Eclipse плагины
  • специалист

Hibernate — Архитектура

Hibernate имеет многоуровневую архитектуру, которая помогает пользователю работать без знания базовых API. Hibernate использует базу данных и данные конфигурации для предоставления приложениям постоянных сервисов (и постоянных объектов).

Ниже приводится очень высокий уровень представления архитектуры приложений Hibernate.

Hibernate High Level View

Ниже приведено подробное представление архитектуры приложений Hibernate с ее важными основными классами.

Архитектура гибернации

Hibernate использует различные существующие API Java, такие как JDBC, API транзакций Java (JTA) и интерфейс именования и каталогов Java (JNDI). JDBC обеспечивает элементарный уровень абстракции функциональности, общей для реляционных баз данных, что позволяет Hibernate поддерживать практически любую базу данных с драйвером JDBC. JNDI и JTA позволяют интегрировать Hibernate с серверами приложений J2EE.

В следующем разделе дается краткое описание каждого из объектов класса, участвующих в Hibernate Application Architecture.

Объект конфигурации

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

Объект конфигурации содержит два ключевых компонента:

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

  • Настройка отображения классов — этот компонент создает связь между классами Java и таблицами базы данных.

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

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

SessionFactory Object

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

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

Объект сеанса

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

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

Объект сделки

Транзакция представляет собой единицу работы с базой данных, и большинство СУБД поддерживает функциональность транзакций. Транзакции в Hibernate обрабатываются соответствующим менеджером транзакций и транзакциями (из JDBC или JTA).

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

Объект запроса

Объекты запросов используют строку SQL или язык запросов Hibernate (HQL) для извлечения данных из базы данных и создания объектов. Экземпляр Query используется для привязки параметров запроса, ограничения количества результатов, возвращаемых запросом, и, наконец, для выполнения запроса.

Критерий Объект

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

Hibernate — Окружающая среда

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

Скачивание Hibernate

Предполагается, что в вашей системе уже установлена ​​последняя версия Java. Ниже приведены простые шаги для загрузки и установки Hibernate в вашей системе:

  • Выберите, хотите ли вы установить Hibernate в Windows или Unix, а затем перейдите к следующему шагу, чтобы загрузить .zip-файл для windows и .tz-файл для Unix.

  • Загрузите последнюю версию Hibernate с http://www.hibernate.org/downloads .

  • На момент написания этого руководства я скачал hibernate-distribution3.6.4.Final, и когда вы распакуете загруженный файл, он даст вам структуру каталогов, как показано на следующем рисунке

Выберите, хотите ли вы установить Hibernate в Windows или Unix, а затем перейдите к следующему шагу, чтобы загрузить .zip-файл для windows и .tz-файл для Unix.

Загрузите последнюю версию Hibernate с http://www.hibernate.org/downloads .

На момент написания этого руководства я скачал hibernate-distribution3.6.4.Final, и когда вы распакуете загруженный файл, он даст вам структуру каталогов, как показано на следующем рисунке

Спящие каталоги

Установка Hibernate

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

  • Теперь скопируйте все файлы библиотеки из / lib в ваш CLASSPATH и измените переменную classpath, чтобы включить все JAR —

  • Наконец, скопируйте файл hibernate3.jar в свой CLASSPATH. Этот файл находится в корневом каталоге установки и является основным JAR, который необходим Hibernate для своей работы.

Теперь скопируйте все файлы библиотеки из / lib в ваш CLASSPATH и измените переменную classpath, чтобы включить все JAR —

Наконец, скопируйте файл hibernate3.jar в свой CLASSPATH. Этот файл находится в корневом каталоге установки и является основным JAR, который необходим Hibernate для своей работы.

Необходимые условия гибернации

Ниже приведен список пакетов / библиотек, необходимых для Hibernate, и вам следует установить их перед началом работы с Hibernate. Чтобы установить эти пакеты, вам нужно будет скопировать файлы библиотеки из / lib в ваш CLASSPATH и соответственно изменить переменную CLASSPATH.

Sr.No. Пакеты / Библиотеки
1

dom4j

Синтаксический анализ XML www.dom4j.org/

2

Xalan

XSLT-процессор https://xml.apache.org/xalan-j/

3

Xerces

Анализатор Java Xerces https://xml.apache.org/xerces-j/

4

CGLIB

Соответствующие изменения в классах Java во время выполнения http://cglib.sourceforge.net/

5

log4j

Ведение журнала Faremwork https://logging.apache.org/log4j

6

Commons

Регистрация, электронная почта и т. Д. Https://jakarta.apache.org/commons

7

SLF4J

Фасад логирования для Java https://www.slf4j.org

dom4j

Синтаксический анализ XML www.dom4j.org/

Xalan

XSLT-процессор https://xml.apache.org/xalan-j/

Xerces

Анализатор Java Xerces https://xml.apache.org/xerces-j/

CGLIB

Соответствующие изменения в классах Java во время выполнения http://cglib.sourceforge.net/

log4j

Ведение журнала Faremwork https://logging.apache.org/log4j

Commons

Регистрация, электронная почта и т. Д. Https://jakarta.apache.org/commons

SLF4J

Фасад логирования для Java https://www.slf4j.org

Hibernate — Конфигурация

Hibernate требует заранее знать — где найти информацию о сопоставлении, которая определяет, как ваши классы Java связаны с таблицами базы данных. Hibernate также требует набора параметров конфигурации, связанных с базой данных и других связанных параметров. Вся такая информация обычно предоставляется в виде стандартного файла свойств Java с именем hibernate.properties или в виде файла XML с именем hibernate.cfg.xml .

Я рассмотрю файл hibernate.cfg.xml в формате XML, чтобы указать необходимые свойства Hibernate в моих примерах. Большинство свойств принимают значения по умолчанию, и нет необходимости указывать их в файле свойств, если это действительно не требуется. Этот файл хранится в корневом каталоге пути к классу вашего приложения.

Спящие свойства

Ниже приведен список важных свойств, вам необходимо будет настроить для баз данных в автономной ситуации —

Sr.No. Свойства и описание
1

hibernate.dialect

Это свойство заставляет Hibernate генерировать соответствующий SQL для выбранной базы данных.

2

hibernate.connection.driver_class

Класс драйвера JDBC.

3

hibernate.connection.url

URL JDBC для экземпляра базы данных.

4

hibernate.connection.username

Имя пользователя базы данных.

5

hibernate.connection.password

Пароль базы данных.

6

hibernate.connection.pool_size

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

7

hibernate.connection.autocommit

Позволяет использовать режим автоматической фиксации для соединения JDBC.

hibernate.dialect

Это свойство заставляет Hibernate генерировать соответствующий SQL для выбранной базы данных.

hibernate.connection.driver_class

Класс драйвера JDBC.

hibernate.connection.url

URL JDBC для экземпляра базы данных.

hibernate.connection.username

Имя пользователя базы данных.

hibernate.connection.password

Пароль базы данных.

hibernate.connection.pool_size

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

hibernate.connection.autocommit

Позволяет использовать режим автоматической фиксации для соединения JDBC.

Если вы используете базу данных вместе с сервером приложений и JNDI, вам придется настроить следующие свойства:

Sr.No. Свойства и описание
1

hibernate.connection.datasource

Имя JNDI, определенное в контексте сервера приложений, которое вы используете для приложения.

2

hibernate.jndi.class

Класс InitialContext для JNDI.

3

hibernate.jndi. <JNDIpropertyname>

Передает любое свойство JNDI, которое вам нравится, в InitialContext JNDI.

4

hibernate.jndi.url

Предоставляет URL для JNDI.

5

hibernate.connection.username

Имя пользователя базы данных.

6

hibernate.connection.password

Пароль базы данных.

hibernate.connection.datasource

Имя JNDI, определенное в контексте сервера приложений, которое вы используете для приложения.

hibernate.jndi.class

Класс InitialContext для JNDI.

hibernate.jndi. <JNDIpropertyname>

Передает любое свойство JNDI, которое вам нравится, в InitialContext JNDI.

hibernate.jndi.url

Предоставляет URL для JNDI.

hibernate.connection.username

Имя пользователя базы данных.

hibernate.connection.password

Пароль базы данных.

Hibernate с базой данных MySQL

MySQL — одна из самых популярных систем баз данных с открытым исходным кодом, доступных сегодня. Давайте создадим файл конфигурации hibernate.cfg.xml и поместим его в корень пути к классу вашего приложения. Вы должны будете убедиться, что у вас есть база данных testdb, доступная в вашей базе данных MySQL, и у вас есть доступный пользовательский тест для доступа к базе данных.

Файл конфигурации XML должен соответствовать DTD конфигурации Hibernate 3, который доступен по адресу http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd .

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
   <session-factory>
   
      <property name = "hibernate.dialect">
         org.hibernate.dialect.MySQLDialect
      </property>
      
      <property name = "hibernate.connection.driver_class">
         com.mysql.jdbc.Driver
      </property>
      
      <!-- Assume test is the database name -->
      
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost/test
      </property>
      
      <property name = "hibernate.connection.username">
         root
      </property>
      
      <property name = "hibernate.connection.password">
         root123
      </property>
      
      <!-- List of XML mapping files -->
      <mapping resource = "Employee.hbm.xml"/>
      
   </session-factory>
</hibernate-configuration>

Приведенный выше файл конфигурации содержит теги <mapping> , которые связаны с файлом hibernatemapping, и в следующей главе мы увидим, что такое файл отображения hibernate и как и почему мы его используем?

Ниже приведен список различных важных типов баз данных диалекта —

Sr.No. База данных и диалект собственности
1

DB2

org.hibernate.dialect.DB2Dialect

2

HSQLDB

org.hibernate.dialect.HSQLDialect

3

HypersonicSQL

org.hibernate.dialect.HSQLDialect

4

Informix

org.hibernate.dialect.InformixDialect

5

Энгр

org.hibernate.dialect.IngresDialect

6

Interbase

org.hibernate.dialect.InterbaseDialect

7

Microsoft SQL Server 2000

org.hibernate.dialect.SQLServerDialect

8

Microsoft SQL Server 2005

org.hibernate.dialect.SQLServer2005Dialect

9

Microsoft SQL Server 2008

org.hibernate.dialect.SQLServer2008Dialect

10

MySQL

org.hibernate.dialect.MySQLDialect

11

Oracle (любая версия)

org.hibernate.dialect.OracleDialect

12

Oracle 11g

org.hibernate.dialect.Oracle10gDialect

13

Oracle 10g

org.hibernate.dialect.Oracle10gDialect

14

Oracle 9i

org.hibernate.dialect.Oracle9iDialect

15

PostgreSQL

org.hibernate.dialect.PostgreSQLDialect

16

Прогресс

org.hibernate.dialect.ProgressDialect

17

SAP DB

org.hibernate.dialect.SAPDBDialect

18

Sybase

org.hibernate.dialect.SybaseDialect

19

Sybase Anywhere

org.hibernate.dialect.SybaseAnywhereDialect

DB2

org.hibernate.dialect.DB2Dialect

HSQLDB

org.hibernate.dialect.HSQLDialect

HypersonicSQL

org.hibernate.dialect.HSQLDialect

Informix

org.hibernate.dialect.InformixDialect

Энгр

org.hibernate.dialect.IngresDialect

Interbase

org.hibernate.dialect.InterbaseDialect

Microsoft SQL Server 2000

org.hibernate.dialect.SQLServerDialect

Microsoft SQL Server 2005

org.hibernate.dialect.SQLServer2005Dialect

Microsoft SQL Server 2008

org.hibernate.dialect.SQLServer2008Dialect

MySQL

org.hibernate.dialect.MySQLDialect

Oracle (любая версия)

org.hibernate.dialect.OracleDialect

Oracle 11g

org.hibernate.dialect.Oracle10gDialect

Oracle 10g

org.hibernate.dialect.Oracle10gDialect

Oracle 9i

org.hibernate.dialect.Oracle9iDialect

PostgreSQL

org.hibernate.dialect.PostgreSQLDialect

Прогресс

org.hibernate.dialect.ProgressDialect

SAP DB

org.hibernate.dialect.SAPDBDialect

Sybase

org.hibernate.dialect.SybaseDialect

Sybase Anywhere

org.hibernate.dialect.SybaseAnywhereDialect

Hibernate — Сессии

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

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

Экземпляры могут существовать в одном из следующих трех состояний в данный момент времени —

  • временный — новый экземпляр постоянного класса, который не связан с сеансом и не представлен в базе данных, а значение идентификатора не считается временным в Hibernate.

  • persistent — вы можете сделать временный экземпляр постоянным, связав его с сеансом. Постоянный экземпляр имеет представление в базе данных, значение идентификатора и связан с сеансом.

  • detached — после того, как мы закроем Hibernate Session, постоянный экземпляр станет отдельным экземпляром.

временный — новый экземпляр постоянного класса, который не связан с сеансом и не представлен в базе данных, а значение идентификатора не считается временным в Hibernate.

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

detached — после того, как мы закроем Hibernate Session, постоянный экземпляр станет отдельным экземпляром.

Экземпляр Session является сериализуемым, если его постоянные классы сериализуемы. Типичная транзакция должна использовать следующую идиому —

Session session = factory.openSession();
Transaction tx = null;

try {
   tx = session.beginTransaction();
   // do some work
   ...
   tx.commit();
}

catch (Exception e) {
   if (tx!=null) tx.rollback();
   e.printStackTrace(); 
} finally {
   session.close();
}

Если сеанс вызывает исключение, транзакция должна быть откатана, а сеанс должен быть отменен.

Методы интерфейса сеанса

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

Sr.No. Методы и описание сессии
1

Транзакция beginTransaction ()

Начните единицу работы и верните связанный объект транзакции.

2

void cancelQuery ()

Отмените выполнение текущего запроса.

3

void clear ()

Полностью очистить сессию.

4

Соединение закрыто ()

Завершите сеанс, освободив соединение JDBC и очистив.

5

Критерии createCriteria (Класс persistentClass)

Создайте новый экземпляр Criteria для данного класса сущности или суперкласса класса сущности.

6

Критерии createCriteria (String entityName)

Создайте новый экземпляр Criteria для данного имени объекта.

7

Сериализуемый getIdentifier (Объектный объект)

Вернуть значение идентификатора данного объекта, связанного с этим сеансом.

8

Запрос createFilter (Коллекция объектов, String queryString)

Создайте новый экземпляр Query для данной коллекции и строку фильтра.

9

Запрос createQuery (String queryString)

Создайте новый экземпляр Query для заданной строки запроса HQL.

10

SQLQuery createSQLQuery (String queryString)

Создайте новый экземпляр SQLQuery для данной строки запроса SQL.

11

void delete (объектный объект)

Удалите постоянный экземпляр из хранилища данных.

12

void delete (String entityName, Object object)

Удалите постоянный экземпляр из хранилища данных.

13

Сеанс get (String entityName, Serializable id)

Вернуть постоянный экземпляр указанного именованного объекта с указанным идентификатором или значение NULL, если такого постоянного экземпляра нет.

14

SessionFactory getSessionFactory ()

Получить фабрику сеансов, которая создала этот сеанс.

15

void refresh (объектный объект)

Перечитайте состояние данного экземпляра из базовой базы данных.

16

Транзакция getTransaction ()

Получить экземпляр транзакции, связанный с этим сеансом.

17

логическое isConnected ()

Проверьте, подключен ли сеанс в данный момент.

18

логическое isDirty ()

Содержит ли этот сеанс какие-либо изменения, которые должны быть синхронизированы с базой данных?

19

логическое isOpen ()

Проверьте, открыт ли сеанс.

20

Сериализуемое сохранение (объектный объект)

Сохраните данный временный экземпляр, сначала назначив сгенерированный идентификатор.

21

void saveOrUpdate (Объектный объект)

Сохраните (Object) или обновите (Object) данный экземпляр.

22

void update (Объектный объект)

Обновите постоянный экземпляр с помощью идентификатора данного отдельного экземпляра.

23

void update (String entityName, Object object)

Обновите постоянный экземпляр с помощью идентификатора данного отдельного экземпляра.

Транзакция beginTransaction ()

Начните единицу работы и верните связанный объект транзакции.

void cancelQuery ()

Отмените выполнение текущего запроса.

void clear ()

Полностью очистить сессию.

Соединение закрыто ()

Завершите сеанс, освободив соединение JDBC и очистив.

Критерии createCriteria (Класс persistentClass)

Создайте новый экземпляр Criteria для данного класса сущности или суперкласса класса сущности.

Критерии createCriteria (String entityName)

Создайте новый экземпляр Criteria для данного имени объекта.

Сериализуемый getIdentifier (Объектный объект)

Вернуть значение идентификатора данного объекта, связанного с этим сеансом.

Запрос createFilter (Коллекция объектов, String queryString)

Создайте новый экземпляр Query для данной коллекции и строку фильтра.

Запрос createQuery (String queryString)

Создайте новый экземпляр Query для заданной строки запроса HQL.

SQLQuery createSQLQuery (String queryString)

Создайте новый экземпляр SQLQuery для данной строки запроса SQL.

void delete (объектный объект)

Удалите постоянный экземпляр из хранилища данных.

void delete (String entityName, Object object)

Удалите постоянный экземпляр из хранилища данных.

Сеанс get (String entityName, Serializable id)

Вернуть постоянный экземпляр указанного именованного объекта с указанным идентификатором или значение NULL, если такого постоянного экземпляра нет.

SessionFactory getSessionFactory ()

Получить фабрику сеансов, которая создала этот сеанс.

void refresh (объектный объект)

Перечитайте состояние данного экземпляра из базовой базы данных.

Транзакция getTransaction ()

Получить экземпляр транзакции, связанный с этим сеансом.

логическое isConnected ()

Проверьте, подключен ли сеанс в данный момент.

логическое isDirty ()

Содержит ли этот сеанс какие-либо изменения, которые должны быть синхронизированы с базой данных?

логическое isOpen ()

Проверьте, открыт ли сеанс.

Сериализуемое сохранение (объектный объект)

Сохраните данный временный экземпляр, сначала назначив сгенерированный идентификатор.

void saveOrUpdate (Объектный объект)

Сохраните (Object) или обновите (Object) данный экземпляр.

void update (Объектный объект)

Обновите постоянный экземпляр с помощью идентификатора данного отдельного экземпляра.

void update (String entityName, Object object)

Обновите постоянный экземпляр с помощью идентификатора данного отдельного экземпляра.

Hibernate — Постоянный класс

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

Классы Java, чьи объекты или экземпляры будут храниться в таблицах базы данных, называются постоянными классами в Hibernate. Hibernate работает лучше всего, если эти классы следуют некоторым простым правилам, также известным как модель программирования Plain Old Java Object (POJO).

Существуют следующие основные правила постоянных классов, однако ни одно из этих правил не является жестким.

  • Все классы Java, которые будут сохранены, нуждаются в конструкторе по умолчанию.

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

  • Все атрибуты, которые будут сохранены, должны быть объявлены закрытыми и иметь методы getXXX и setXXX, определенные в стиле JavaBean.

  • Центральная особенность прокси-серверов Hibernate зависит от того, является ли постоянный класс не финальным, или от реализации интерфейса, который объявляет все открытые методы.

  • Все классы, которые не расширяют или не реализуют некоторые специализированные классы и интерфейсы, требуемые EJB-инфраструктурой.

Все классы Java, которые будут сохранены, нуждаются в конструкторе по умолчанию.

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

Все атрибуты, которые будут сохранены, должны быть объявлены закрытыми и иметь методы getXXX и setXXX, определенные в стиле JavaBean.

Центральная особенность прокси-серверов Hibernate зависит от того, является ли постоянный класс не финальным, или от реализации интерфейса, который объявляет все открытые методы.

Все классы, которые не расширяют или не реализуют некоторые специализированные классы и интерфейсы, требуемые EJB-инфраструктурой.

Имя POJO используется, чтобы подчеркнуть, что данный объект является обычным Java-объектом, а не специальным объектом и, в частности, не Enterprise JavaBean.

Простой пример POJO

Основываясь на нескольких правилах, упомянутых выше, мы можем определить класс POJO следующим образом:

public class Employee {
   private int id;
   private String firstName; 
   private String lastName;   
   private int salary;  

   public Employee() {}
   public Employee(String fname, String lname, int salary) {
      this.firstName = fname;
      this.lastName = lname;
      this.salary = salary;
   }
   
   public int getId() {
      return id;
   }
   
   public void setId( int id ) {
      this.id = id;
   }
   
   public String getFirstName() {
      return firstName;
   }
   
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   
   public String getLastName() {
      return lastName;
   }
   
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   
   public int getSalary() {
      return salary;
   }
   
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}

Hibernate — Файлы сопоставления

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

Хотя многие пользователи Hibernate предпочитают писать XML вручную, существует целый ряд инструментов для создания документа сопоставления. К ним относятся XDoclet, Middlegen и AndroMDA для продвинутых пользователей Hibernate.

Давайте рассмотрим наш ранее определенный класс POJO, чьи объекты будут сохраняться в таблице, определенной в следующем разделе.

public class Employee {
   private int id;
   private String firstName; 
   private String lastName;   
   private int salary;  

   public Employee() {}
   
   public Employee(String fname, String lname, int salary) {
      this.firstName = fname;
      this.lastName = lname;
      this.salary = salary;
   }
   
   public int getId() {
      return id;
   }
   
   public void setId( int id ) {
      this.id = id;
   }
   
   public String getFirstName() {
      return firstName;
   }
   
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   
   public String getLastName() {
      return lastName;
   }
   
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   
   public int getSalary() {
      return salary;
   }
   
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}

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

create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

Основываясь на двух вышеуказанных сущностях, мы можем определить следующий файл сопоставления, который инструктирует Hibernate, как сопоставить определенный класс или классы с таблицами базы данных.

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

<hibernate-mapping>
   <class name = "Employee" table = "EMPLOYEE">
      
      <meta attribute = "class-description">
         This class contains the employee detail. 
      </meta>
      
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
      
      <property name = "firstName" column = "first_name" type = "string"/>
      <property name = "lastName" column = "last_name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>
      
   </class>
</hibernate-mapping>

Вы должны сохранить документ сопоставления в файле в формате <classname> .hbm.xml. Мы сохранили наш документ сопоставления в файле Employee.hbm.xml.

Давайте разберемся в деталях об элементах отображения, используемых в файле отображения —

  • Документ сопоставления представляет собой XML-документ, имеющий в качестве корневого элемента <hibernate-mapping> , который содержит все элементы <class> .

  • Элементы <class> используются для определения конкретных отображений из классов Java в таблицы базы данных. Имя класса Java указывается с помощью атрибута name элемента class, а имя таблицы базы данных указывается с помощью атрибута table.

  • Элемент <meta> является необязательным и может использоваться для создания описания класса.

  • Элемент <id> сопоставляет атрибут уникального идентификатора в классе с первичным ключом таблицы базы данных. Атрибут name элемента id ссылается на свойство в классе, а атрибут column ссылается на столбец в таблице базы данных. Атрибут type содержит тип отображения hibernate, при этом типы отображения преобразуются из Java в тип данных SQL.

  • Элемент <generator> в элементе id используется для автоматической генерации значений первичного ключа. Атрибут class элемента генератора установлен на native, чтобы позволить hibernate подобрать алгоритм идентичности, последовательности или hilo для создания первичного ключа в зависимости от возможностей базовой базы данных.

  • Элемент <property> используется для сопоставления свойства класса Java со столбцом в таблице базы данных. Атрибут имени элемента ссылается на свойство в классе, а атрибут столбца ссылается на столбец в таблице базы данных. Атрибут type содержит тип отображения hibernate, при этом типы отображения преобразуются из Java в тип данных SQL.

Документ сопоставления представляет собой XML-документ, имеющий в качестве корневого элемента <hibernate-mapping> , который содержит все элементы <class> .

Элементы <class> используются для определения конкретных отображений из классов Java в таблицы базы данных. Имя класса Java указывается с помощью атрибута name элемента class, а имя таблицы базы данных указывается с помощью атрибута table.

Элемент <meta> является необязательным и может использоваться для создания описания класса.

Элемент <id> сопоставляет атрибут уникального идентификатора в классе с первичным ключом таблицы базы данных. Атрибут name элемента id ссылается на свойство в классе, а атрибут column ссылается на столбец в таблице базы данных. Атрибут type содержит тип отображения hibernate, при этом типы отображения преобразуются из Java в тип данных SQL.

Элемент <generator> в элементе id используется для автоматической генерации значений первичного ключа. Атрибут class элемента генератора установлен на native, чтобы позволить hibernate подобрать алгоритм идентичности, последовательности или hilo для создания первичного ключа в зависимости от возможностей базовой базы данных.

Элемент <property> используется для сопоставления свойства класса Java со столбцом в таблице базы данных. Атрибут имени элемента ссылается на свойство в классе, а атрибут столбца ссылается на столбец в таблице базы данных. Атрибут type содержит тип отображения hibernate, при этом типы отображения преобразуются из Java в тип данных SQL.

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

Спящий режим — Типы картографирования

Когда вы готовите документ отображения Hibernate, вы обнаруживаете, что сопоставляете типы данных Java с типами данных RDBMS. Типы, объявленные и используемые в файлах сопоставления, не являются типами данных Java; они также не являются типами баз данных SQL. Эти типы называются типами отображения Hibernate , которые могут переводиться из типов данных Java в SQL и наоборот.

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

Примитивные типы

Тип отображения Тип Java Тип ANSI SQL
целое число int или java.lang.Integer INTEGER
долго длинный или java.lang.Long BIGINT
короткая короткий или java.lang.Short SMALLINT
поплавок плавать или java.lang.Float FLOAT
двойной double или java.lang. Double DOUBLE
big_decimal java.math.BigDecimal NUMERIC
персонаж java.lang.String СИМ (1)
строка java.lang.String VARCHAR
байт байт или java.lang.Byte TINYINT
логический логическое или java.lang. булево НЕМНОГО
да нет логическое или java.lang. булево CHAR (1) («Y» или «N»)
истина / ложь логическое или java.lang. булево CHAR (1) («T» или «F»)

Типы даты и времени

Тип отображения Тип Java Тип ANSI SQL
Дата java.util.Date или java.sql.Date ДАТА
время java.util.Date или java.sql.Time ВРЕМЯ
отметка времени java.util.Date или java.sql.Timestamp TIMESTAMP
календарь java.util.Calendar TIMESTAMP
calendar_date java.util.Calendar ДАТА

Двоичные и крупные типы объектов

Тип отображения Тип Java Тип ANSI SQL
двоичный байт[] VARBINARY (или BLOB)
текст java.lang.String CLOB
сериализуемым любой класс Java, который реализует java.io.Serializable VARBINARY (или BLOB)
CLOB java.sql.Clob CLOB
капля java.sql.Blob большой двоичный объект

JDK-связанные типы

Тип отображения Тип Java Тип ANSI SQL
учебный класс java.lang.Class VARCHAR
место действия java.util.Locale VARCHAR
часовой пояс java.util.TimeZone VARCHAR
валюта java.util.Currency VARCHAR

Hibernate — Примеры

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

Создать классы POJO

Первым шагом в создании приложения является создание класса или классов Java POJO в зависимости от приложения, которое будет сохранено в базе данных. Давайте рассмотрим наш класс Employee с методами getXXX и setXXX, чтобы сделать его совместимым с JavaBeans классом.

POJO (обычный старый Java-объект) — это Java-объект, который не расширяет и не реализует некоторые специализированные классы и интерфейсы, требуемые инфраструктурой EJB соответственно. Все обычные объекты Java являются POJO.

Когда вы разрабатываете класс для сохранения в Hibernate, важно предоставить совместимый с JavaBeans код, а также один атрибут, который будет работать как индексный атрибут id в классе Employee.

public class Employee {
   private int id;
   private String firstName; 
   private String lastName;   
   private int salary;  

   public Employee() {}
   public Employee(String fname, String lname, int salary) {
      this.firstName = fname;
      this.lastName = lname;
      this.salary = salary;
   }
   
   public int getId() {
      return id;
   }
   
   public void setId( int id ) {
      this.id = id;
   }
   
   public String getFirstName() {
      return firstName;
   }
   
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   
   public String getLastName() {
      return lastName;
   }
   
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   
   public int getSalary() {
      return salary;
   }
   
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}

Создать таблицы базы данных

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

create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

Создать файл конфигурации сопоставления

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

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

<hibernate-mapping>
   <class name = "Employee" table = "EMPLOYEE">
      
      <meta attribute = "class-description">
         This class contains the employee detail. 
      </meta>
      
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
      
      <property name = "firstName" column = "first_name" type = "string"/>
      <property name = "lastName" column = "last_name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>
      
   </class>
</hibernate-mapping>

Вы должны сохранить документ сопоставления в файле в формате <classname> .hbm.xml. Мы сохранили наш документ сопоставления в файле Employee.hbm.xml. Давайте посмотрим немного подробнее о картографическом документе —

  • Документ сопоставления — это документ XML, имеющий в качестве корневого элемента <hibernate-mapping>, который содержит все элементы <class>.

  • Элементы <class> используются для определения конкретных отображений из классов Java в таблицы базы данных. Имя класса Java указывается с помощью атрибута name элемента class, а имя таблицы базы данных указывается с помощью атрибута table .

  • Элемент <meta> является необязательным и может использоваться для создания описания класса.

  • Элемент <id> сопоставляет атрибут уникального идентификатора в классе с первичным ключом таблицы базы данных. Атрибут name элемента id ссылается на свойство в классе, а атрибут column ссылается на столбец в таблице базы данных. Атрибут type содержит тип отображения hibernate, при этом типы отображения преобразуются из Java в тип данных SQL.

  • Элемент <generator> в элементе id используется для автоматической генерации значений первичного ключа. Атрибут class элемента генератора установлен на native, чтобы позволить hibernate подобрать алгоритм идентификации, последовательности или hilo для создания первичного ключа в зависимости от возможностей базовой базы данных.

  • Элемент <property> используется для сопоставления свойства класса Java со столбцом в таблице базы данных. Атрибут имени элемента ссылается на свойство в классе, а атрибут столбца ссылается на столбец в таблице базы данных. Атрибут type содержит тип отображения hibernate, при этом типы отображения преобразуются из Java в тип данных SQL.

Документ сопоставления — это документ XML, имеющий в качестве корневого элемента <hibernate-mapping>, который содержит все элементы <class>.

Элементы <class> используются для определения конкретных отображений из классов Java в таблицы базы данных. Имя класса Java указывается с помощью атрибута name элемента class, а имя таблицы базы данных указывается с помощью атрибута table .

Элемент <meta> является необязательным и может использоваться для создания описания класса.

Элемент <id> сопоставляет атрибут уникального идентификатора в классе с первичным ключом таблицы базы данных. Атрибут name элемента id ссылается на свойство в классе, а атрибут column ссылается на столбец в таблице базы данных. Атрибут type содержит тип отображения hibernate, при этом типы отображения преобразуются из Java в тип данных SQL.

Элемент <generator> в элементе id используется для автоматической генерации значений первичного ключа. Атрибут class элемента генератора установлен на native, чтобы позволить hibernate подобрать алгоритм идентификации, последовательности или hilo для создания первичного ключа в зависимости от возможностей базовой базы данных.

Элемент <property> используется для сопоставления свойства класса Java со столбцом в таблице базы данных. Атрибут имени элемента ссылается на свойство в классе, а атрибут столбца ссылается на столбец в таблице базы данных. Атрибут type содержит тип отображения hibernate, при этом типы отображения преобразуются из Java в тип данных SQL.

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

Создать класс приложения

Наконец, мы создадим наш класс приложения с методом main () для запуска приложения. Мы будем использовать это приложение для сохранения нескольких записей сотрудника, а затем будем применять операции CRUD к этим записям.

import java.util.List; 
import java.util.Date;
import java.util.Iterator; 
 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {
   private static SessionFactory factory; 
   public static void main(String[] args) {
      
      try {
         factory = new Configuration().configure().buildSessionFactory();
      } catch (Throwable ex) { 
         System.err.println("Failed to create sessionFactory object." + ex);
         throw new ExceptionInInitializerError(ex); 
      }
      
      ManageEmployee ME = new ManageEmployee();

      /* Add few employee records in database */
      Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
      Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
      Integer empID3 = ME.addEmployee("John", "Paul", 10000);

      /* List down all the employees */
      ME.listEmployees();

      /* Update employee's records */
      ME.updateEmployee(empID1, 5000);

      /* Delete an employee from the database */
      ME.deleteEmployee(empID2);

      /* List down new list of the employees */
      ME.listEmployees();
   }
   
   /* Method to CREATE an employee in the database */
   public Integer addEmployee(String fname, String lname, int salary){
      Session session = factory.openSession();
      Transaction tx = null;
      Integer employeeID = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = new Employee(fname, lname, salary);
         employeeID = (Integer) session.save(employee); 
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
      return employeeID;
   }
   
   /* Method to  READ all the employees */
   public void listEmployees( ){
      Session session = factory.openSession();
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         List employees = session.createQuery("FROM Employee").list(); 
         for (Iterator iterator = employees.iterator(); iterator.hasNext();){
            Employee employee = (Employee) iterator.next(); 
            System.out.print("First Name: " + employee.getFirstName()); 
            System.out.print("  Last Name: " + employee.getLastName()); 
            System.out.println("  Salary: " + employee.getSalary()); 
         }
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
   
   /* Method to UPDATE salary for an employee */
   public void updateEmployee(Integer EmployeeID, int salary ){
      Session session = factory.openSession();
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = (Employee)session.get(Employee.class, EmployeeID); 
         employee.setSalary( salary );
		 session.update(employee); 
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
   
   /* Method to DELETE an employee from the records */
   public void deleteEmployee(Integer EmployeeID){
      Session session = factory.openSession();
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = (Employee)session.get(Employee.class, EmployeeID); 
         session.delete(employee); 
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
}

Компиляция и выполнение

Вот шаги для компиляции и запуска вышеупомянутого приложения. Убедитесь, что вы правильно установили PATH и CLASSPATH, прежде чем приступить к компиляции и выполнению.

  • Создайте файл конфигурации hibernate.cfg.xml, как описано в главе о конфигурации.

  • Создайте файл сопоставления Employee.hbm.xml, как показано выше.

  • Создайте исходный файл Employee.java, как показано выше, и скомпилируйте его.

  • Создайте исходный файл ManageEmployee.java, как показано выше, и скомпилируйте его.

  • Выполните двоичный файл ManageEmployee, чтобы запустить программу.

Создайте файл конфигурации hibernate.cfg.xml, как описано в главе о конфигурации.

Создайте файл сопоставления Employee.hbm.xml, как показано выше.

Создайте исходный файл Employee.java, как показано выше, и скомпилируйте его.

Создайте исходный файл ManageEmployee.java, как показано выше, и скомпилируйте его.

Выполните двоичный файл ManageEmployee, чтобы запустить программу.

Вы получите следующий результат, и записи будут созданы в таблице EMPLOYEE.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Zara  Last Name: Ali  Salary: 1000
First Name: Daisy  Last Name: Das  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000
First Name: Zara  Last Name: Ali  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000

Если вы проверите свою таблицу EMPLOYEE, она должна иметь следующие записи:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 29 | Zara       | Ali       |   5000 |
| 31 | John       | Paul      |  10000 |
+----+------------+-----------+--------+
2 rows in set (0.00 sec

mysql>

Hibernate — O / R Mappings

До сих пор мы видели очень простое отображение O / R, используя hibernate, но есть три наиболее важных темы отображения, которые мы должны изучить подробно.

Это —

  • Составление карт коллекций,
  • Отображение связей между классами сущностей и
  • Сопоставления компонентов.

Коллекции сопоставлений

Если у сущности или класса есть коллекция значений для определенной переменной, то мы можем отобразить эти значения, используя любой из интерфейсов коллекции, доступных в Java. Hibernate может сохранять экземпляры java.util.Map, java.util.Set, java.util.SortedMap, java.util.SortedSet, java.util.List и любой массив постоянных сущностей или значений.

Sr.No. Тип коллекции и описание карт
1 java.util.Set

Это сопоставляется с элементом <set> и инициализируется с помощью java.util.HashSet.

2 java.util.SortedSet

Это отображается с помощью элемента <set> и инициализируется с помощью java.util.TreeSet. Атрибут sort может быть установлен как в компараторе, так и в естественном порядке.

3 java.util.List

Это сопоставляется с элементом <list> и инициализируется с помощью java.util.ArrayList

4 java.util.Collection

Это отображается с помощью элемента <bag> или <ibag> и инициализируется с помощью java.util.ArrayList

5 java.util.Map

Это сопоставляется с элементом <map> и инициализируется с помощью java.util.HashMap.

6 java.util.SortedMap

Это отображается с помощью элемента <map> и инициализируется с помощью java.util.TreeMap. Атрибут sort может быть установлен как в компараторе, так и в естественном порядке.

Это сопоставляется с элементом <set> и инициализируется с помощью java.util.HashSet.

Это отображается с помощью элемента <set> и инициализируется с помощью java.util.TreeSet. Атрибут sort может быть установлен как в компараторе, так и в естественном порядке.

Это сопоставляется с элементом <list> и инициализируется с помощью java.util.ArrayList

Это отображается с помощью элемента <bag> или <ibag> и инициализируется с помощью java.util.ArrayList

Это сопоставляется с элементом <map> и инициализируется с помощью java.util.HashMap.

Это отображается с помощью элемента <map> и инициализируется с помощью java.util.TreeMap. Атрибут sort может быть установлен как в компараторе, так и в естественном порядке.

Hibernate поддерживает массивы с <primitive-array> для типов примитивных значений Java и <array> для всего остального. Однако они используются редко, поэтому я не буду обсуждать их в этом уроке.

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

Ассоциация сопоставлений

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

Sr.No. Тип отображения и описание
1 Многие-к-одному

Отображение отношений «многие к одному» с использованием Hibernate

2 Один к одному

Отображение отношений один-к-одному с помощью Hibernate

3 Один ко многим

Отображение отношения один ко многим с помощью Hibernate

4 Многие-ко-многим

Отображение отношений «многие ко многим» с использованием Hibernate

Отображение отношений «многие к одному» с использованием Hibernate

Отображение отношений один-к-одному с помощью Hibernate

Отображение отношения один ко многим с помощью Hibernate

Отображение отношений «многие ко многим» с использованием Hibernate

Сопоставления компонентов

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

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

Sr.No. Тип отображения и описание
1 Сопоставления компонентов

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

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

Спящий режим — Аннотации

До сих пор вы видели, как Hibernate использует файл сопоставления XML для преобразования данных из POJO в таблицы базы данных и наоборот. Hibernate аннотации являются новейшим способом определения сопоставлений без использования файла XML. Вы можете использовать аннотации в дополнение или в качестве замены метаданных отображения XML.

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

Если вы собираетесь сделать свое приложение переносимым на другие совместимые с EJB 3 приложения ORM, вы должны использовать аннотации для представления информации о сопоставлении, но, тем не менее, если вы хотите большей гибкости, вам следует использовать сопоставления на основе XML.

Настройка среды для спящего аннотации

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

Во-вторых, вам нужно установить дистрибутив аннотаций Hibernate 3.x, доступный из sourceforge: ( Скачать аннотацию Hibernate ), и скопировать hibernate-annotations.jar, lib / hibernate-comons-annotations.jar и lib / ejb3-persistence. jar из дистрибутива Hibernate Annotations для вашего CLASSPATH.

Пример аннотированного класса

Как я упоминал выше при работе с Hibernate Annotation, все метаданные объединяются в Java-файл POJO вместе с кодом, это помогает пользователю одновременно понимать структуру таблицы и POJO во время разработки.

Предположим, мы собираемся использовать следующую таблицу EMPLOYEE для хранения наших объектов:

create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

Ниже приведено сопоставление класса Employee с аннотациями для сопоставления объектов с определенной таблицей EMPLOYEE.

import javax.persistence.*;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {
   @Id @GeneratedValue
   @Column(name = "id")
   private int id;

   @Column(name = "first_name")
   private String firstName;

   @Column(name = "last_name")
   private String lastName;

   @Column(name = "salary")
   private int salary;  

   public Employee() {}
   
   public int getId() {
      return id;
   }
   
   public void setId( int id ) {
      this.id = id;
   }
   
   public String getFirstName() {
      return firstName;
   }
   
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   
   public String getLastName() {
      return lastName;
   }
   
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   
   public int getSalary() {
      return salary;
   }
   
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}

Hibernate обнаруживает, что аннотация @Id находится в поле, и предполагает, что он должен обращаться к свойствам объекта напрямую через поля во время выполнения. Если вы поместите аннотацию @Id в метод getId (), вы по умолчанию разрешите доступ к свойствам через методы getter и setter. Следовательно, все остальные аннотации также размещаются в полях или методах получения в соответствии с выбранной стратегией.

Следующий раздел объяснит аннотации, используемые в вышеприведенном классе.

@Entity Annotation

Стандартные аннотации EJB 3 содержатся в пакете javax.persistence , поэтому мы импортируем этот пакет в качестве первого шага. Во-вторых, мы использовали аннотацию @Entity для класса Employee, который помечает этот класс как объектный компонент, поэтому он должен иметь конструктор без аргументов, видимый как минимум с защищенной областью действия.

@Table Annotation

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

Аннотация @Table предоставляет четыре атрибута, позволяющих переопределить имя таблицы, ее каталог и ее схему, а также применить уникальные ограничения для столбцов в таблице. На данный момент мы используем только имя таблицы, которая является EMPLOYEE.

Аннотации @Id и @GeneratedValue

Каждый объектный компонент будет иметь первичный ключ, который вы аннотируете в классе с помощью аннотации @Id . Первичный ключ может быть одним полем или комбинацией нескольких полей в зависимости от структуры таблицы.

По умолчанию аннотация @Id автоматически определяет наиболее подходящую стратегию генерации первичного ключа, но вы можете переопределить ее, применив аннотацию @GeneratedValue , которая использует стратегию с двумя параметрами и генератор, которые я не буду обсуждать здесь, поэтому давайте использовать только стратегию генерации ключей по умолчанию. Разрешение Hibernate определять, какой тип генератора использовать, делает ваш код переносимым между различными базами данных.

@ Колонка Аннотация

Аннотация @Column используется для указания сведений о столбце, в который будет отображаться поле или свойство. Вы можете использовать аннотацию столбца со следующими наиболее часто используемыми атрибутами:

  • Атрибут name позволяет явно указать имя столбца.

  • Атрибут length разрешает размер столбца, используемого для сопоставления значения, особенно для значения String.

  • Атрибут nullable позволяет пометить столбец NOT NULL при создании схемы.

  • Атрибут unique позволяет пометить столбец как содержащий только уникальные значения.

Атрибут name позволяет явно указать имя столбца.

Атрибут length разрешает размер столбца, используемого для сопоставления значения, особенно для значения String.

Атрибут nullable позволяет пометить столбец NOT NULL при создании схемы.

Атрибут unique позволяет пометить столбец как содержащий только уникальные значения.

Создать класс приложения

Наконец, мы создадим наш класс приложения с методом main () для запуска приложения. Мы будем использовать это приложение для сохранения нескольких записей сотрудника, а затем будем применять операции CRUD к этим записям.

import java.util.List; 
import java.util.Date;
import java.util.Iterator; 
 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {
   private static SessionFactory factory; 
   public static void main(String[] args) {
      
      try {
         factory = new AnnotationConfiguration().
                   configure().
                   //addPackage("com.xyz") //add package if used.
                   addAnnotatedClass(Employee.class).
                   buildSessionFactory();
      } catch (Throwable ex) { 
         System.err.println("Failed to create sessionFactory object." + ex);
         throw new ExceptionInInitializerError(ex); 
      }
      
      ManageEmployee ME = new ManageEmployee();

      /* Add few employee records in database */
      Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
      Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
      Integer empID3 = ME.addEmployee("John", "Paul", 10000);

      /* List down all the employees */
      ME.listEmployees();

      /* Update employee's records */
      ME.updateEmployee(empID1, 5000);

      /* Delete an employee from the database */
      ME.deleteEmployee(empID2);

      /* List down new list of the employees */
      ME.listEmployees();
   }
   
   /* Method to CREATE an employee in the database */
   public Integer addEmployee(String fname, String lname, int salary){
      Session session = factory.openSession();
      Transaction tx = null;
      Integer employeeID = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = new Employee();
         employee.setFirstName(fname);
         employee.setLastName(lname);
         employee.setSalary(salary);
         employeeID = (Integer) session.save(employee); 
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
      return employeeID;
   }
   
   /* Method to  READ all the employees */
   public void listEmployees( ){
      Session session = factory.openSession();
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         List employees = session.createQuery("FROM Employee").list(); 
         for (Iterator iterator = employees.iterator(); iterator.hasNext();){
            Employee employee = (Employee) iterator.next(); 
            System.out.print("First Name: " + employee.getFirstName()); 
            System.out.print("  Last Name: " + employee.getLastName()); 
            System.out.println("  Salary: " + employee.getSalary()); 
         }
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
   
   /* Method to UPDATE salary for an employee */
   public void updateEmployee(Integer EmployeeID, int salary ){
      Session session = factory.openSession();
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = (Employee)session.get(Employee.class, EmployeeID); 
         employee.setSalary( salary );
		 session.update(employee); 
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
   
   /* Method to DELETE an employee from the records */
   public void deleteEmployee(Integer EmployeeID){
      Session session = factory.openSession();
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = (Employee)session.get(Employee.class, EmployeeID); 
         session.delete(employee); 
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
}

Конфигурация базы данных

Теперь давайте создадим файл конфигурации hibernate.cfg.xml для определения параметров, связанных с базой данных.

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
   <session-factory>
   
      <property name = "hibernate.dialect">
         org.hibernate.dialect.MySQLDialect
      </property>
   
      <property name = "hibernate.connection.driver_class">
         com.mysql.jdbc.Driver
      </property>

      <!-- Assume students is the database name -->
   
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost/test
      </property>
   
      <property name = "hibernate.connection.username">
         root
      </property>
   
      <property name = "hibernate.connection.password">
         cohondob
      </property>

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

Компиляция и выполнение

Вот шаги для компиляции и запуска вышеупомянутого приложения. Убедитесь, что вы правильно установили PATH и CLASSPATH, прежде чем приступить к компиляции и выполнению.

  • Удалите файл сопоставления Employee.hbm.xml из пути.

  • Создайте исходный файл Employee.java, как показано выше, и скомпилируйте его.

  • Создайте исходный файл ManageEmployee.java, как показано выше, и скомпилируйте его.

  • Выполните двоичный файл ManageEmployee, чтобы запустить программу.

Удалите файл сопоставления Employee.hbm.xml из пути.

Создайте исходный файл Employee.java, как показано выше, и скомпилируйте его.

Создайте исходный файл ManageEmployee.java, как показано выше, и скомпилируйте его.

Выполните двоичный файл ManageEmployee, чтобы запустить программу.

Вы получите следующий результат, и записи будут созданы в таблице EMPLOYEE.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Zara  Last Name: Ali  Salary: 1000
First Name: Daisy  Last Name: Das  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000
First Name: Zara  Last Name: Ali  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000

Если вы проверите свою таблицу EMPLOYEE, она должна иметь следующие записи:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 29 | Zara       | Ali       |   5000 |
| 31 | John       | Paul      |  10000 |
+----+------------+-----------+--------+
2 rows in set (0.00 sec

mysql>

Hibernate — Язык запросов

Hibernate Query Language (HQL) — это объектно-ориентированный язык запросов, похожий на SQL, но вместо работы с таблицами и столбцами HQL работает с постоянными объектами и их свойствами. HQL-запросы преобразуются Hibernate в обычные SQL-запросы, которые, в свою очередь, выполняют действия с базой данных.

Хотя вы можете использовать операторы SQL непосредственно с Hibernate, используя Native SQL, но я бы порекомендовал использовать HQL, когда это возможно, чтобы избежать проблем с переносимостью баз данных и воспользоваться преимуществами стратегий генерации и кэширования SQL в Hibernate.

Ключевые слова, такие как SELECT, FROM, WHERE и т. Д., Не чувствительны к регистру, но такие свойства, как имена таблиц и столбцов, чувствительны к регистру в HQL.

ОТ клаузулы

Вы будете использовать предложение FROM , если хотите загрузить полностью постоянные объекты в память. Ниже приведен простой синтаксис использования предложения FROM —

String hql = "FROM Employee";
Query query = session.createQuery(hql);
List results = query.list();

Если вам нужно полностью указать имя класса в HQL, просто укажите пакет и имя класса следующим образом:

String hql = "FROM com.hibernatebook.criteria.Employee";
Query query = session.createQuery(hql);
List results = query.list();

AS пункт

Предложение AS можно использовать для назначения псевдонимов классам в ваших HQL-запросах, особенно если у вас длинные запросы. Например, наш предыдущий простой пример будет следующим:

String hql = "FROM Employee AS E";
Query query = session.createQuery(hql);
List results = query.list();

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

String hql = "FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

ВЫБРАТЬ пункт

Предложение SELECT обеспечивает больший контроль над результирующим набором, чем предложение from. Если вы хотите получить несколько свойств объектов вместо всего объекта, используйте предложение SELECT. Ниже приведен простой синтаксис использования предложения SELECT для получения только поля first_name объекта Employee.

String hql = "SELECT E.firstName FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

Следует отметить, что Employee.firstName является свойством объекта Employee, а не полем таблицы EMPLOYEE.

ГДЕ оговорка

Если вы хотите сузить конкретные объекты, которые возвращаются из хранилища, используйте предложение WHERE. Ниже приведен простой синтаксис использования предложения WHERE:

String hql = "FROM Employee E WHERE E.id = 10";
Query query = session.createQuery(hql);
List results = query.list();

ЗАКАЗАТЬ по пункту

Чтобы отсортировать результаты вашего HQL-запроса, вам нужно использовать предложение ORDER BY . Вы можете упорядочить результаты по любому свойству объектов в наборе результатов по возрастанию (ASC) или по убыванию (DESC). Ниже приведен простой синтаксис использования предложения ORDER BY:

String hql = "FROM Employee E WHERE E.id > 10 ORDER BY E.salary DESC";
Query query = session.createQuery(hql);
List results = query.list();

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

String hql = "FROM Employee E WHERE E.id > 10 " +
             "ORDER BY E.firstName DESC, E.salary DESC ";
Query query = session.createQuery(hql);
List results = query.list();

Предложение GROUP BY

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

String hql = "SELECT SUM(E.salary), E.firtName FROM Employee E " +
             "GROUP BY E.firstName";
Query query = session.createQuery(hql);
List results = query.list();

Использование именованных параметров

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

String hql = "FROM Employee E WHERE E.id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("employee_id",10);
List results = query.list();

ОБНОВЛЕНИЕ

Массовые обновления являются новыми для HQL с Hibernate 3, и удаляют работу в Hibernate 3 иначе, чем в Hibernate 2. Интерфейс Query теперь содержит метод executeUpdate () для выполнения операторов HQL UPDATE или DELETE.

Предложение UPDATE может использоваться для обновления одного или нескольких свойств одного или нескольких объектов. Ниже приведен простой синтаксис использования предложения UPDATE —

String hql = "UPDATE Employee set salary = :salary "  + 
             "WHERE id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("salary", 1000);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

УДАЛИТЬ пункт

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

String hql = "DELETE FROM Employee "  + 
             "WHERE id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("employee_id", 10);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

Вставить пункт

HQL поддерживает предложение INSERT INTO только тогда, когда записи могут быть вставлены из одного объекта в другой. Ниже приведен простой синтаксис использования предложения INSERT INTO:

String hql = "INSERT INTO Employee(firstName, lastName, salary)"  + 
             "SELECT firstName, lastName, salary FROM old_employee";
Query query = session.createQuery(hql);
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

Агрегатные методы

HQL поддерживает ряд агрегатных методов, похожих на SQL. Они работают так же, как в HQL, так и в SQL, и ниже приведен список доступных функций:

Sr.No. Функции и описание
1

avg (название объекта)

Средняя стоимость имущества

2

считать (имя свойства или *)

Сколько раз свойство встречается в результатах

3

max (имя свойства)

Максимальное значение значения свойства

4

мин (название объекта)

Минимальное значение значения свойства

5

сумма (название объекта)

Общая сумма стоимости имущества

avg (название объекта)

Средняя стоимость имущества

считать (имя свойства или *)

Сколько раз свойство встречается в результатах

max (имя свойства)

Максимальное значение значения свойства

мин (название объекта)

Минимальное значение значения свойства

сумма (название объекта)

Общая сумма стоимости имущества

Отдельное ключевое слово учитывает только уникальные значения в наборе строк. Следующий запрос вернет только уникальный счет —

String hql = "SELECT count(distinct E.firstName) FROM Employee E";
Query query = session.createQuery(hql);
List results = query.list();

Нумерация страниц с использованием запроса

Существует два метода интерфейса Query для разбивки на страницы.

Sr.No. Метод и описание
1

Запрос setFirstResult (int startPosition)

Этот метод принимает целое число, представляющее первую строку в вашем наборе результатов, начиная со строки 0.

2

Запрос setMaxResults (int maxResult)

Этот метод сообщает Hibernate о получении фиксированного числа maxResults объектов.

Запрос setFirstResult (int startPosition)

Этот метод принимает целое число, представляющее первую строку в вашем наборе результатов, начиная со строки 0.

Запрос setMaxResults (int maxResult)

Этот метод сообщает Hibernate о получении фиксированного числа maxResults объектов.

Используя два вышеупомянутых метода вместе, мы можем создать пейджинговый компонент в нашем веб-приложении или приложении Swing. Ниже приведен пример, который вы можете расширить, чтобы получить 10 строк за раз:

String hql = "FROM Employee";
Query query = session.createQuery(hql);
query.setFirstResult(1);
query.setMaxResults(10);
List results = query.list();

Hibernate — Критерии Запросы

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

Интерфейс Hibernate Session предоставляет метод createCriteria () , который можно использовать для создания объекта Criteria, который возвращает экземпляры класса объекта постоянства, когда ваше приложение выполняет запрос критерия.

Ниже приведен простейший пример критерия запроса, который просто возвращает каждый объект, соответствующий классу Employee.

Criteria cr = session.createCriteria(Employee.class);
List results = cr.list();

Ограничения с критериями

Вы можете использовать метод add (), доступный для объекта Criteria, чтобы добавить ограничение для запроса критерия. Ниже приведен пример добавления ограничения для возврата записей с зарплатой, равной 2000 —

Criteria cr = session.createCriteria(Employee.class);
cr.add(Restrictions.eq("salary", 2000));
List results = cr.list();

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

Criteria cr = session.createCriteria(Employee.class);

// To get records having salary more than 2000
cr.add(Restrictions.gt("salary", 2000));

// To get records having salary less than 2000
cr.add(Restrictions.lt("salary", 2000));

// To get records having fistName starting with zara
cr.add(Restrictions.like("firstName", "zara%"));

// Case sensitive form of the above restriction.
cr.add(Restrictions.ilike("firstName", "zara%"));

// To get records having salary in between 1000 and 2000
cr.add(Restrictions.between("salary", 1000, 2000));

// To check if the given property is null
cr.add(Restrictions.isNull("salary"));

// To check if the given property is not null
cr.add(Restrictions.isNotNull("salary"));

// To check if the given property is empty
cr.add(Restrictions.isEmpty("salary"));

// To check if the given property is not empty
cr.add(Restrictions.isNotEmpty("salary"));

Вы можете создать условия И или ИЛИ, используя ограничения LogicalExpression следующим образом:

Criteria cr = session.createCriteria(Employee.class);

Criterion salary = Restrictions.gt("salary", 2000);
Criterion name = Restrictions.ilike("firstNname","zara%");

// To get records matching with OR conditions
LogicalExpression orExp = Restrictions.or(salary, name);
cr.add( orExp );

// To get records matching with AND conditions
LogicalExpression andExp = Restrictions.and(salary, name);
cr.add( andExp );

List results = cr.list();

Хотя все вышеперечисленные условия могут быть использованы непосредственно с HQL, как описано в предыдущем уроке.

Нумерация страниц по критериям

Существует два метода интерфейса Criteria для разбивки на страницы.

Sr.No. Метод и описание
1

общедоступные критерии setFirstResult (int firstResult)

Этот метод принимает целое число, представляющее первую строку в вашем наборе результатов, начиная со строки 0.

2

общедоступные критерии setMaxResults (int maxResults)

Этот метод сообщает Hibernate о получении фиксированного числа maxResults объектов.

общедоступные критерии setFirstResult (int firstResult)

Этот метод принимает целое число, представляющее первую строку в вашем наборе результатов, начиная со строки 0.

общедоступные критерии setMaxResults (int maxResults)

Этот метод сообщает Hibernate о получении фиксированного числа maxResults объектов.

Используя два вышеупомянутых метода вместе, мы можем создать пейджинговый компонент в нашем веб-приложении или приложении Swing. Ниже приведен пример, который вы можете расширить, чтобы получить 10 строк за раз:

Criteria cr = session.createCriteria(Employee.class);
cr.setFirstResult(1);
cr.setMaxResults(10);
List results = cr.list();

Сортировка результатов

API Criteria предоставляет класс org.hibernate.criterion.Order для сортировки набора результатов в порядке возрастания или убывания в соответствии с одним из свойств вашего объекта. В этом примере показано, как использовать класс Order для сортировки набора результатов.

Criteria cr = session.createCriteria(Employee.class);

// To get records having salary more than 2000
cr.add(Restrictions.gt("salary", 2000));

// To sort records in descening order
cr.addOrder(Order.desc("salary"));

// To sort records in ascending order
cr.addOrder(Order.asc("salary"));

List results = cr.list();

Прогнозы и агрегаты

API Criteria предоставляет класс org.hibernate.criterion.Projection , который можно использовать для получения среднего, максимального или минимального значений свойств. Класс Projection аналогичен классу Restrictions в том, что он предоставляет несколько статических фабричных методов для получения экземпляров Projection .

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

Criteria cr = session.createCriteria(Employee.class);

// To get total row count.
cr.setProjection(Projections.rowCount());

// To get average of a property.
cr.setProjection(Projections.avg("salary"));

// To get distinct count of a property.
cr.setProjection(Projections.countDistinct("firstName"));

// To get maximum of a property.
cr.setProjection(Projections.max("salary"));

// To get minimum of a property.
cr.setProjection(Projections.min("salary"));

// To get sum of a property.
cr.setProjection(Projections.sum("salary"));

Пример критериев запросов

Рассмотрим следующий класс POJO —

public class Employee {
   private int id;
   private String firstName; 
   private String lastName;   
   private int salary;  

   public Employee() {}
   
   public Employee(String fname, String lname, int salary) {
      this.firstName = fname;
      this.lastName = lname;
      this.salary = salary;
   }
   
   public int getId() {
      return id;
   }
   
   public void setId( int id ) {
      this.id = id;
   }
   
   public String getFirstName() {
      return firstName;
   }
   
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   
   public String getLastName() {
      return lastName;
   }
   
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   
   public int getSalary() {
      return salary;
   }
   
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}

Давайте создадим следующую таблицу EMPLOYEE для хранения объектов Employee —

create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

Ниже будет файл сопоставления.

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

<hibernate-mapping>
   <class name = "Employee" table = "EMPLOYEE">
      
      <meta attribute = "class-description">
         This class contains the employee detail. 
      </meta>
      
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
      
      <property name = "firstName" column = "first_name" type = "string"/>
      <property name = "lastName" column = "last_name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>
      
   </class>
</hibernate-mapping>

Наконец, мы создадим наш класс приложения с методом main () для запуска приложения, в котором мы будем использовать запросы Criteria.

import java.util.List; 
import java.util.Date;
import java.util.Iterator; 
 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Projections;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {
   private static SessionFactory factory; 
   public static void main(String[] args) {
      
      try {
         factory = new Configuration().configure().buildSessionFactory();
      } catch (Throwable ex) { 
         System.err.println("Failed to create sessionFactory object." + ex);
         throw new ExceptionInInitializerError(ex); 
      }
      
      ManageEmployee ME = new ManageEmployee();

      /* Add few employee records in database */
      Integer empID1 = ME.addEmployee("Zara", "Ali", 2000);
      Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
      Integer empID3 = ME.addEmployee("John", "Paul", 5000);
      Integer empID4 = ME.addEmployee("Mohd", "Yasee", 3000);

      /* List down all the employees */
      ME.listEmployees();

      /* Print Total employee's count */
      ME.countEmployee();

      /* Print Total salary */
      ME.totalSalary();
   }
   
   /* Method to CREATE an employee in the database */
   public Integer addEmployee(String fname, String lname, int salary){
      Session session = factory.openSession();
      Transaction tx = null;
      Integer employeeID = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = new Employee(fname, lname, salary);
         employeeID = (Integer) session.save(employee); 
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
      return employeeID;
   }

   /* Method to  READ all the employees having salary more than 2000 */
   public void listEmployees( ) {
      Session session = factory.openSession();
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         Criteria cr = session.createCriteria(Employee.class);
         // Add restriction.
         cr.add(Restrictions.gt("salary", 2000));
         List employees = cr.list();

         for (Iterator iterator = employees.iterator(); iterator.hasNext();){
            Employee employee = (Employee) iterator.next(); 
            System.out.print("First Name: " + employee.getFirstName()); 
            System.out.print("  Last Name: " + employee.getLastName()); 
            System.out.println("  Salary: " + employee.getSalary()); 
         }
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
   
   /* Method to print total number of records */
   public void countEmployee(){
      Session session = factory.openSession();
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         Criteria cr = session.createCriteria(Employee.class);

         // To get total row count.
         cr.setProjection(Projections.rowCount());
         List rowCount = cr.list();

         System.out.println("Total Coint: " + rowCount.get(0) );
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
  
   /* Method to print sum of salaries */
   public void totalSalary(){
      Session session = factory.openSession();
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         Criteria cr = session.createCriteria(Employee.class);

         // To get total salary.
         cr.setProjection(Projections.sum("salary"));
         List totalSalary = cr.list();

         System.out.println("Total Salary: " + totalSalary.get(0) );
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
}

Компиляция и выполнение

Вот шаги для компиляции и запуска вышеупомянутого приложения. Убедитесь, что вы правильно установили PATH и CLASSPATH, прежде чем приступить к компиляции и выполнению.

  • Создайте файл конфигурации hibernate.cfg.xml, как описано в главе о конфигурации.

  • Создайте файл сопоставления Employee.hbm.xml, как показано выше.

  • Создайте исходный файл Employee.java, как показано выше, и скомпилируйте его.

  • Создайте исходный файл ManageEmployee.java, как показано выше, и скомпилируйте его.

  • Выполните двоичный файл ManageEmployee, чтобы запустить программу.

Создайте файл конфигурации hibernate.cfg.xml, как описано в главе о конфигурации.

Создайте файл сопоставления Employee.hbm.xml, как показано выше.

Создайте исходный файл Employee.java, как показано выше, и скомпилируйте его.

Создайте исходный файл ManageEmployee.java, как показано выше, и скомпилируйте его.

Выполните двоичный файл ManageEmployee, чтобы запустить программу.

Вы получите следующий результат, и записи будут созданы в таблице EMPLOYEE.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Daisy  Last Name: Das  Salary: 5000
First Name: John  Last Name: Paul  Salary: 5000
First Name: Mohd  Last Name: Yasee  Salary: 3000
Total Coint: 4
Total Salary: 15000

Если вы проверите свою таблицу EMPLOYEE, она должна иметь следующие записи:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 14 | Zara       | Ali       |   2000 |
| 15 | Daisy      | Das       |   5000 |
| 16 | John       | Paul      |   5000 |
| 17 | Mohd       | Yasee     |   3000 |
+----+------------+-----------+--------+
4 rows in set (0.00 sec)
mysql>

Hibernate — собственный SQL

Вы можете использовать собственный SQL для выражения запросов к базе данных, если хотите использовать специфичные для базы данных функции, такие как подсказки запросов или ключевое слово CONNECT в Oracle. Hibernate 3.x позволяет указывать рукописный SQL, включая хранимые процедуры, для всех операций создания, обновления, удаления и загрузки.

Ваше приложение создаст собственный запрос SQL из сеанса с помощью метода createSQLQuery () в интерфейсе сеанса —

public SQLQuery createSQLQuery(String sqlString) throws HibernateException

После передачи строки, содержащей запрос SQL, в метод createSQLQuery () можно связать результат SQL с существующей сущностью Hibernate, объединением или скалярным результатом, используя методы addEntity (), addJoin () и addScalar (). соответственно.

Скалярные Запросы

Самый простой запрос SQL — это получить список скаляров (значений) из одной или нескольких таблиц. Ниже приведен синтаксис использования собственного SQL для скалярных значений:

String sql = "SELECT first_name, salary FROM EMPLOYEE";
SQLQuery query = session.createSQLQuery(sql);
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List results = query.list();

Entity Queries

Все вышеперечисленные запросы касались возврата скалярных значений, в основном возвращая «сырые» значения из набора результатов. Ниже приведен синтаксис для получения объектов сущности в целом из собственного SQL-запроса с помощью addEntity ().

String sql = "SELECT * FROM EMPLOYEE";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Employee.class);
List results = query.list();

Именованные SQL-запросы

Ниже приведен синтаксис для получения объектов сущности из собственного SQL-запроса с помощью addEntity () и использования именованного SQL-запроса.

String sql = "SELECT * FROM EMPLOYEE WHERE id = :employee_id";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity(Employee.class);
query.setParameter("employee_id", 10);
List results = query.list();

Пример собственного SQL

Рассмотрим следующий класс POJO —

public class Employee {
   private int id;
   private String firstName; 
   private String lastName;   
   private int salary;  

   public Employee() {}
   
   public Employee(String fname, String lname, int salary) {
      this.firstName = fname;
      this.lastName = lname;
      this.salary = salary;
   }
   
   public int getId() {
      return id;
   }
   
   public void setId( int id ) {
      this.id = id;
   }
   
   public String getFirstName() {
      return firstName;
   }
   
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   
   public String getLastName() {
      return lastName;
   }
   
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   
   public int getSalary() {
      return salary;
   }
   
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}

Давайте создадим следующую таблицу EMPLOYEE для хранения объектов Employee —

create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

Ниже будет файл сопоставления —

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

<hibernate-mapping>
   <class name = "Employee" table = "EMPLOYEE">
      
      <meta attribute = "class-description">
         This class contains the employee detail. 
      </meta>
      
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
      
      <property name = "firstName" column = "first_name" type = "string"/>
      <property name = "lastName" column = "last_name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>
      
   </class>
</hibernate-mapping>

Наконец, мы создадим наш класс приложения с методом main () для запуска приложения, в котором мы будем использовать собственные запросы SQL

import java.util.*; 
 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.SQLQuery;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {
   private static SessionFactory factory; 
   public static void main(String[] args) {
      
      try {
         factory = new Configuration().configure().buildSessionFactory();
      } catch (Throwable ex) { 
         System.err.println("Failed to create sessionFactory object." + ex);
         throw new ExceptionInInitializerError(ex); 
      }
      
      ManageEmployee ME = new ManageEmployee();

      /* Add few employee records in database */
      Integer empID1 = ME.addEmployee("Zara", "Ali", 2000);
      Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
      Integer empID3 = ME.addEmployee("John", "Paul", 5000);
      Integer empID4 = ME.addEmployee("Mohd", "Yasee", 3000);

      /* List down employees and their salary using Scalar Query */
      ME.listEmployeesScalar();

      /* List down complete employees information using Entity Query */
      ME.listEmployeesEntity();
   }
   
   /* Method to CREATE an employee in the database */
   public Integer addEmployee(String fname, String lname, int salary){
      Session session = factory.openSession();
      Transaction tx = null;
      Integer employeeID = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = new Employee(fname, lname, salary);
         employeeID = (Integer) session.save(employee); 
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
      return employeeID;
   }

   /* Method to  READ all the employees using Scalar Query */
   public void listEmployeesScalar( ){
      Session session = factory.openSession();
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         String sql = "SELECT first_name, salary FROM EMPLOYEE";
         SQLQuery query = session.createSQLQuery(sql);
         query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
         List data = query.list();

         for(Object object : data) {
            Map row = (Map)object;
            System.out.print("First Name: " + row.get("first_name")); 
            System.out.println(", Salary: " + row.get("salary")); 
         }
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }

   /* Method to READ all the employees using Entity Query */
   public void listEmployeesEntity( ){
      Session session = factory.openSession();
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         String sql = "SELECT * FROM EMPLOYEE";
         SQLQuery query = session.createSQLQuery(sql);
         query.addEntity(Employee.class);
         List employees = query.list();

         for (Iterator iterator = employees.iterator(); iterator.hasNext();){
            Employee employee = (Employee) iterator.next(); 
            System.out.print("First Name: " + employee.getFirstName()); 
            System.out.print("  Last Name: " + employee.getLastName()); 
            System.out.println("  Salary: " + employee.getSalary()); 
         }
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
}

Компиляция и выполнение

Вот шаги для компиляции и запуска вышеупомянутого приложения. Убедитесь, что вы правильно установили PATH и CLASSPATH, прежде чем приступить к компиляции и выполнению.

  • Создайте файл конфигурации hibernate.cfg.xml, как описано в главе о конфигурации.

  • Создайте файл сопоставления Employee.hbm.xml, как показано выше.

  • Создайте исходный файл Employee.java, как показано выше, и скомпилируйте его.

  • Создайте исходный файл ManageEmployee.java, как показано выше, и скомпилируйте его.

  • Выполните двоичный файл ManageEmployee, чтобы запустить программу.

Создайте файл конфигурации hibernate.cfg.xml, как описано в главе о конфигурации.

Создайте файл сопоставления Employee.hbm.xml, как показано выше.

Создайте исходный файл Employee.java, как показано выше, и скомпилируйте его.

Создайте исходный файл ManageEmployee.java, как показано выше, и скомпилируйте его.

Выполните двоичный файл ManageEmployee, чтобы запустить программу.

Вы получите следующий результат, и записи будут созданы в таблице EMPLOYEE.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

First Name: Zara, Salary: 2000
First Name: Daisy, Salary: 5000
First Name: John, Salary: 5000
First Name: Mohd, Salary: 3000
First Name: Zara  Last Name: Ali  Salary: 2000
First Name: Daisy  Last Name: Das  Salary: 5000
First Name: John  Last Name: Paul  Salary: 5000
First Name: Mohd  Last Name: Yasee  Salary: 3000

Если вы проверите свою таблицу EMPLOYEE, она должна иметь следующие записи:

mysql> select * from EMPLOYEE;
+----+------------+-----------+--------+
| id | first_name | last_name | salary |
+----+------------+-----------+--------+
| 26 | Zara       | Ali       |   2000 |
| 27 | Daisy      | Das       |   5000 |
| 28 | John       | Paul      |   5000 |
| 29 | Mohd       | Yasee     |   3000 |
+----+------------+-----------+--------+
4 rows in set (0.00 sec)
mysql>

Hibernate — Кэширование

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

Кеширование также важно для Hibernate. Он использует многоуровневую схему кэширования, как описано ниже —

Hibernate Кэширование

Кэш первого уровня

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

Если вы выпускаете несколько обновлений для объекта, Hibernate пытается отложить выполнение обновления как можно дольше, чтобы уменьшить количество выпущенных операторов SQL обновления. Если вы закроете сеанс, все кэшируемые объекты будут потеряны и сохранены или обновлены в базе данных.

Кэш второго уровня

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

Любой сторонний кеш может быть использован с Hibernate. Предоставляется интерфейс org.hibernate.cache.CacheProvider , который должен быть реализован, чтобы обеспечить Hibernate дескриптором реализации кэша.

Кэш на уровне запросов

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

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

Кэш второго уровня

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

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

Стратегии параллелизма

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

  • Транзакционный. Используйте эту стратегию для данных, предназначенных главным образом для чтения, где важно предотвратить устаревшие данные в параллельных транзакциях в редких случаях обновления.

  • Чтение-запись — снова используйте эту стратегию для данных, предназначенных главным образом для чтения, где важно предотвратить устаревшие данные в параллельных транзакциях, в редких случаях обновления.

  • Nonstrict-read-write — эта стратегия не гарантирует согласованности между кешем и базой данных. Используйте эту стратегию, если данные почти никогда не изменяются и небольшая вероятность устаревших данных не является критической проблемой.

  • Только для чтения — стратегия параллелизма, подходящая для данных, которая никогда не изменяется. Используйте его только для справочных данных.

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

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

Nonstrict-read-write — эта стратегия не гарантирует согласованности между кешем и базой данных. Используйте эту стратегию, если данные почти никогда не изменяются и небольшая вероятность устаревших данных не является критической проблемой.

Только для чтения — стратегия параллелизма, подходящая для данных, которая никогда не изменяется. Используйте его только для справочных данных.

Если мы собираемся использовать кэширование второго уровня для нашего класса Employee , добавим элемент отображения, необходимый для того, чтобы Hibernate кэшировал экземпляры Employee, используя стратегию чтения-записи.

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping>
   <class name = "Employee" table = "EMPLOYEE">
      
      <meta attribute = "class-description">
         This class contains the employee detail. 
      </meta>
      
      <cache usage = "read-write"/>
      
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
      
      <property name = "firstName" column = "first_name" type = "string"/>
      <property name = "lastName" column = "last_name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>
      
   </class>
</hibernate-mapping>

Атрибут use = «read-write» указывает Hibernate использовать стратегию параллельного чтения и записи для определенного кэша.

Поставщик кэша

Следующим шагом после рассмотрения стратегий параллелизма станет использование классов-кандидатов в кэш для выбора поставщика кеша. Hibernate заставляет вас выбирать одного поставщика кеша для всего приложения.

Sr.No. Имя и описание кэша
1

EHCache

Он может кэшироваться в памяти или на диске, а также в кластерном кэшировании и поддерживает дополнительный кэш результатов запроса Hibernate.

2

OSCache

Поддерживает кэширование в память и на диск в одной JVM с богатым набором политик истечения срока действия и поддержкой кэша запросов.

3

warmCache

Кластерный кеш на основе JGroups. Он использует кластеризованную аннулирование, но не поддерживает кэш запросов Hibernate.

4

JBoss Cache

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

EHCache

Он может кэшироваться в памяти или на диске, а также в кластерном кэшировании и поддерживает дополнительный кэш результатов запроса Hibernate.

OSCache

Поддерживает кэширование в память и на диск в одной JVM с богатым набором политик истечения срока действия и поддержкой кэша запросов.

warmCache

Кластерный кеш на основе JGroups. Он использует кластеризованную аннулирование, но не поддерживает кэш запросов Hibernate.

JBoss Cache

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

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

Стратегия / Provider Только для чтения Nonstrictread-записи Читай пиши транзакционный
EHCache Икс Икс Икс
OSCache Икс Икс Икс
SwarmCache Икс Икс
JBoss Cache Икс Икс

Вы будете указывать поставщика кеша в файле конфигурации hibernate.cfg.xml. Мы выбираем EHCache в качестве нашего поставщика кэша второго уровня —

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
   <session-factory>
   
      <property name = "hibernate.dialect">
         org.hibernate.dialect.MySQLDialect
      </property>
   
      <property name = "hibernate.connection.driver_class">
         com.mysql.jdbc.Driver
      </property>
   
      <!-- Assume students is the database name -->
   
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost/test
      </property>
   
      <property name = "hibernate.connection.username">
         root
      </property>
   
      <property name = "hibernate.connection.password">
         root123
      </property>
   
      <property name = "hibernate.cache.provider_class">
         org.hibernate.cache.EhCacheProvider
      </property>
   
      <!-- List of XML mapping files -->
      <mapping resource = "Employee.hbm.xml"/>
   
   </session-factory>
</hibernate-configuration>

Теперь вам нужно указать свойства областей кэша. EHCache имеет свой собственный файл конфигурации, ehcache.xml , который должен находиться в CLASSPATH приложения. Конфигурация кэша в ehcache.xml для класса Employee может выглядеть так:

<diskStore path="java.io.tmpdir"/>

<defaultCache
maxElementsInMemory = "1000"
eternal = "false"
timeToIdleSeconds = "120"
timeToLiveSeconds = "120"
overflowToDisk = "true"
/>

<cache name = "Employee"
maxElementsInMemory = "500"
eternal = "true"
timeToIdleSeconds = "0"
timeToLiveSeconds = "0"
overflowToDisk = "false"
/>

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

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

Кэш на уровне запросов

Чтобы использовать кэш запросов, сначала необходимо активировать его, используя свойство hibernate.cache.use_query_cache = «true» в файле конфигурации. Установив для этого свойства значение true, вы заставляете Hibernate создавать необходимые кеши в памяти для хранения наборов запросов и идентификаторов.

Далее, чтобы использовать кеш запросов, вы используете метод setCacheable (Boolean) класса Query. Например —

Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
List users = query.list();
SessionFactory.closeSession();

Hibernate также поддерживает очень тонкую поддержку кэша благодаря концепции области кэша. Регион кеша является частью кеша, которому дано имя.

Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
query.setCacheRegion("employee");
List users = query.list();
SessionFactory.closeSession();

Этот код использует метод, чтобы сообщить Hibernate хранить и искать запрос в области кэша сотрудников.

Hibernate — Пакетная обработка

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

Session session = SessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
   Employee employee = new Employee(.....);
   session.save(employee);
}
tx.commit();
session.close();

По умолчанию Hibernate будет кэшировать все сохраненные объекты в кэше на уровне сеанса, и в конечном итоге ваше приложение будет сброшено с OutOfMemoryException где-то около 50 000-й строки. Вы можете решить эту проблему, если вы используете пакетную обработку с Hibernate.

Чтобы использовать функцию пакетной обработки, сначала установите hibernate.jdbc.batch_size в качестве размера пакета равным 20 или 50, в зависимости от размера объекта. Это сообщит Hibernate контейнеру, что каждые X строк должны быть вставлены в пакетном режиме. Чтобы реализовать это в вашем коде, нам нужно будет сделать небольшое изменение следующим образом:

Session session = SessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
   Employee employee = new Employee(.....);
   session.save(employee);
   if( i % 50 == 0 ) { // Same as the JDBC batch size
      //flush a batch of inserts and release memory:
      session.flush();
      session.clear();
   }
}
tx.commit();
session.close();

Приведенный выше код будет нормально работать для операции INSERT, но если вы захотите выполнить операцию UPDATE, вы можете добиться с помощью следующего кода:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

ScrollableResults employeeCursor = session.createQuery("FROM EMPLOYEE").scroll();
int count = 0;

while ( employeeCursor.next() ) {
   Employee employee = (Employee) employeeCursor.get(0);
   employee.updateEmployee();
   seession.update(employee); 
   if ( ++count % 50 == 0 ) {
      session.flush();
      session.clear();
   }
}
tx.commit();
session.close();

Пример пакетной обработки

Давайте изменим файл конфигурации, добавив свойство hibernate.jdbc.batch_size

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
   <session-factory>
   
      <property name = "hibernate.dialect">
         org.hibernate.dialect.MySQLDialect
      </property>
   
      <property name = "hibernate.connection.driver_class">
         com.mysql.jdbc.Driver
      </property>

      <!-- Assume students is the database name -->
   
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost/test
      </property>
   
      <property name = "hibernate.connection.username">
         root
      </property>
   
      <property name = "hibernate.connection.password">
         root123
      </property>
   
      <property name = "hibernate.jdbc.batch_size">
         50
      </property>

      <!-- List of XML mapping files -->
      <mapping resource = "Employee.hbm.xml"/>

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

Рассмотрим следующий класс сотрудников POJO —

public class Employee {
   private int id;
   private String firstName; 
   private String lastName;   
   private int salary;  

   public Employee() {}
   
   public Employee(String fname, String lname, int salary) {
      this.firstName = fname;
      this.lastName = lname;
      this.salary = salary;
   }
   
   public int getId() {
      return id;
   }
   
   public void setId( int id ) {
      this.id = id;
   }
   
   public String getFirstName() {
      return firstName;
   }
   
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   
   public String getLastName() {
      return lastName;
   }
   
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   
   public int getSalary() {
      return salary;
   }
   
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}

Давайте создадим следующую таблицу EMPLOYEE для хранения объектов Employee —

create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

Ниже будет файл сопоставления для сопоставления объектов Employee с таблицей EMPLOYEE —

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

<hibernate-mapping>
   <class name = "Employee" table = "EMPLOYEE">
      
      <meta attribute = "class-description">
         This class contains the employee detail. 
      </meta>
      
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
      
      <property name = "firstName" column = "first_name" type = "string"/>
      <property name = "lastName" column = "last_name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>
      
   </class>
</hibernate-mapping>

Наконец, мы создадим наш класс приложения с методом main () для запуска приложения, в котором мы будем использовать методы flush () и clear (), доступные в объекте Session, чтобы Hibernate продолжал записывать эти записи в базу данных, а не кэшировать их в объем памяти.

import java.util.*; 
 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {
   private static SessionFactory factory; 
   public static void main(String[] args) {
      
      try {
         factory = new Configuration().configure().buildSessionFactory();
      } catch (Throwable ex) { 
         System.err.println("Failed to create sessionFactory object." + ex);
         throw new ExceptionInInitializerError(ex); 
      }
      ManageEmployee ME = new ManageEmployee();

      /* Add employee records in batches */
      ME.addEmployees( );
   }
   
   /* Method to create employee records in batches */
   public void addEmployees( ){
      Session session = factory.openSession();
      Transaction tx = null;
      Integer employeeID = null;
      
      try {
         tx = session.beginTransaction();
         for ( int i=0; i<100000; i++ ) {
            String fname = "First Name " + i;
            String lname = "Last Name " + i;
            Integer salary = i;
            Employee employee = new Employee(fname, lname, salary);
            session.save(employee);
         	if( i % 50 == 0 ) {
               session.flush();
               session.clear();
            }
         }
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
      return ;
   }
}

Компиляция и выполнение

Вот шаги для компиляции и запуска вышеупомянутого приложения. Убедитесь, что вы правильно установили PATH и CLASSPATH, прежде чем приступить к компиляции и выполнению.

  • Создайте файл конфигурации hibernate.cfg.xml, как описано выше.

  • Создайте файл сопоставления Employee.hbm.xml, как показано выше.

  • Создайте исходный файл Employee.java, как показано выше, и скомпилируйте его.

  • Создайте исходный файл ManageEmployee.java, как показано выше, и скомпилируйте его.

  • Выполните двоичный файл ManageEmployee, чтобы запустить программу, которая создаст 100000 записей в таблице EMPLOYEE.

Создайте файл конфигурации hibernate.cfg.xml, как описано выше.

Создайте файл сопоставления Employee.hbm.xml, как показано выше.

Создайте исходный файл Employee.java, как показано выше, и скомпилируйте его.

Создайте исходный файл ManageEmployee.java, как показано выше, и скомпилируйте его.

Выполните двоичный файл ManageEmployee, чтобы запустить программу, которая создаст 100000 записей в таблице EMPLOYEE.

Hibernate — Перехватчики

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

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

Sr.No. Метод и описание
1

findDirty ()

Этот метод вызывается, когда метод flush () вызывается для объекта Session.

2

экземпляр ()

Этот метод вызывается, когда создается экземпляр постоянного класса.

3

isUnsaved ()

Этот метод вызывается, когда объект передается методу saveOrUpdate () /

4

OnDelete ()

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

5

onFlushDirty ()

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

6

в процессе()

Этот метод вызывается до инициализации объекта.

7

OnSave ()

Этот метод вызывается перед сохранением объекта.

8

postFlush ()

Этот метод вызывается после сброса и обновления объекта в памяти.

9

промывочная ()

Этот метод вызывается перед сбросом.

findDirty ()

Этот метод вызывается, когда метод flush () вызывается для объекта Session.

экземпляр ()

Этот метод вызывается, когда создается экземпляр постоянного класса.

isUnsaved ()

Этот метод вызывается, когда объект передается методу saveOrUpdate () /

OnDelete ()

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

onFlushDirty ()

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

в процессе()

Этот метод вызывается до инициализации объекта.

OnSave ()

Этот метод вызывается перед сохранением объекта.

postFlush ()

Этот метод вызывается после сброса и обновления объекта в памяти.

промывочная ()

Этот метод вызывается перед сбросом.

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

Как использовать перехватчики?

Чтобы создать перехватчик, вы можете либо напрямую реализовать класс Interceptor, либо расширить класс EmptyInterceptor . Далее будут простые шаги по использованию функциональности Hibernate Interceptor.

Создать перехватчики

Мы расширим EmptyInterceptor в нашем примере, где метод Interceptor будет вызываться автоматически при создании и обновлении объекта Employee . Вы можете реализовать больше методов в соответствии с вашими требованиями.

import java.io.Serializable;
import java.util.Date;
import java.util.Iterator;

import org.hibernate.EmptyInterceptor;
import org.hibernate.Transaction;
import org.hibernate.type.Type;

public class MyInterceptor extends EmptyInterceptor {
   private int updates;
   private int creates;
   private int loads;

   public void onDelete(Object entity, Serializable id,
      Object[] state, String[] propertyNames, Type[] types) {
       // do nothing
   }

   // This method is called when Employee object gets updated.
   public boolean onFlushDirty(Object entity, Serializable id,
      Object[] currentState, Object[] previousState, String[] propertyNames,
      Type[] types) {
         if ( entity instanceof Employee ) {
            System.out.println("Update Operation");
            return true; 
         }
         return false;
   }
	
   public boolean onLoad(Object entity, Serializable id,
      Object[] state, String[] propertyNames, Type[] types) {
         // do nothing
         return true;
   }
   
   // This method is called when Employee object gets created.
   public boolean onSave(Object entity, Serializable id,
      Object[] state, String[] propertyNames, Type[] types) {
         if ( entity instanceof Employee ) {
            System.out.println("Create Operation");
            return true; 
         }
         return false;
   }
   
   //called before commit into database
   public void preFlush(Iterator iterator) {
      System.out.println("preFlush");
   }
   
   //called after committed into database
   public void postFlush(Iterator iterator) {
      System.out.println("postFlush");
   }
}

Создать классы POJO

Теперь давайте немного изменим наш первый пример, в котором мы использовали таблицу EMPLOYEE и класс Employee для игры —

public class Employee {
   private int id;
   private String firstName; 
   private String lastName;   
   private int salary;  

   public Employee() {}
   
   public Employee(String fname, String lname, int salary) {
      this.firstName = fname;
      this.lastName = lname;
      this.salary = salary;
   }
   
   public int getId() {
      return id;
   }
   
   public void setId( int id ) {
      this.id = id;
   }
   
   public String getFirstName() {
      return firstName;
   }
   
   public void setFirstName( String first_name ) {
      this.firstName = first_name;
   }
   
   public String getLastName() {
      return lastName;
   }
   
   public void setLastName( String last_name ) {
      this.lastName = last_name;
   }
   
   public int getSalary() {
      return salary;
   }
   
   public void setSalary( int salary ) {
      this.salary = salary;
   }
}

Создать таблицы базы данных

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

create table EMPLOYEE (
   id INT NOT NULL auto_increment,
   first_name VARCHAR(20) default NULL,
   last_name  VARCHAR(20) default NULL,
   salary     INT  default NULL,
   PRIMARY KEY (id)
);

Создать файл конфигурации сопоставления

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

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

<hibernate-mapping>
   <class name = "Employee" table = "EMPLOYEE">
      
      <meta attribute = "class-description">
         This class contains the employee detail. 
      </meta>
      
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
      
      <property name = "firstName" column = "first_name" type = "string"/>
      <property name = "lastName" column = "last_name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>
      
   </class>
</hibernate-mapping>

Создать класс приложения

Наконец, мы создадим наш класс приложения с методом main () для запуска приложения. Здесь следует отметить, что при создании объекта сеанса мы использовали наш класс Interceptor в качестве аргумента.

import java.util.List; 
import java.util.Date;
import java.util.Iterator; 
 
import org.hibernate.HibernateException; 
import org.hibernate.Session; 
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ManageEmployee {
   private static SessionFactory factory; 
   public static void main(String[] args) {
      
      try {
         factory = new Configuration().configure().buildSessionFactory();
      } catch (Throwable ex) { 
         System.err.println("Failed to create sessionFactory object." + ex);
         throw new ExceptionInInitializerError(ex); 
      }

      ManageEmployee ME = new ManageEmployee();

      /* Add few employee records in database */
      Integer empID1 = ME.addEmployee("Zara", "Ali", 1000);
      Integer empID2 = ME.addEmployee("Daisy", "Das", 5000);
      Integer empID3 = ME.addEmployee("John", "Paul", 10000);

      /* List down all the employees */
      ME.listEmployees();

      /* Update employee's records */
      ME.updateEmployee(empID1, 5000);

      /* Delete an employee from the database */
      ME.deleteEmployee(empID2);

      /* List down new list of the employees */
      ME.listEmployees();
   }
   
   /* Method to CREATE an employee in the database */
   public Integer addEmployee(String fname, String lname, int salary){
      Session session = factory.openSession( new MyInterceptor() );
      Transaction tx = null;
      Integer employeeID = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = new Employee(fname, lname, salary);
         employeeID = (Integer) session.save(employee); 
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
      return employeeID;
   }
   
   /* Method to  READ all the employees */
   public void listEmployees( ){
      Session session = factory.openSession( new MyInterceptor() );
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         List employees = session.createQuery("FROM Employee").list(); 
         for (Iterator iterator = employees.iterator(); iterator.hasNext();){
            Employee employee = (Employee) iterator.next(); 
            System.out.print("First Name: " + employee.getFirstName()); 
            System.out.print("  Last Name: " + employee.getLastName()); 
            System.out.println("  Salary: " + employee.getSalary()); 
         }
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
   
   /* Method to UPDATE salary for an employee */
   public void updateEmployee(Integer EmployeeID, int salary ){
      Session session = factory.openSession( new MyInterceptor() );
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = (Employee)session.get(Employee.class, EmployeeID); 
         employee.setSalary( salary );
		 session.update(employee); 
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
   
   /* Method to DELETE an employee from the records */
   public void deleteEmployee(Integer EmployeeID){
      Session session = factory.openSession( new MyInterceptor() );
      Transaction tx = null;
      
      try {
         tx = session.beginTransaction();
         Employee employee = (Employee)session.get(Employee.class, EmployeeID); 
         session.delete(employee); 
         tx.commit();
      } catch (HibernateException e) {
         if (tx!=null) tx.rollback();
         e.printStackTrace(); 
      } finally {
         session.close(); 
      }
   }
}

Компиляция и выполнение

Вот шаги для компиляции и запуска вышеупомянутого приложения. Убедитесь, что вы правильно установили PATH и CLASSPATH, прежде чем приступить к компиляции и выполнению.

  • Создайте файл конфигурации hibernate.cfg.xml, как описано в главе о конфигурации.

  • Создайте файл сопоставления Employee.hbm.xml, как показано выше.

  • Создайте исходный файл Employee.java, как показано выше, и скомпилируйте его.

  • Создайте исходный файл MyInterceptor.java, как показано выше, и скомпилируйте его.

  • Создайте исходный файл ManageEmployee.java, как показано выше, и скомпилируйте его.

  • Выполните двоичный файл ManageEmployee, чтобы запустить программу.

Создайте файл конфигурации hibernate.cfg.xml, как описано в главе о конфигурации.

Создайте файл сопоставления Employee.hbm.xml, как показано выше.

Создайте исходный файл Employee.java, как показано выше, и скомпилируйте его.

Создайте исходный файл MyInterceptor.java, как показано выше, и скомпилируйте его.

Создайте исходный файл ManageEmployee.java, как показано выше, и скомпилируйте его.

Выполните двоичный файл ManageEmployee, чтобы запустить программу.

Вы получите следующий результат, и записи будут созданы в таблице EMPLOYEE.

$java ManageEmployee
.......VARIOUS LOG MESSAGES WILL DISPLAY HERE........

Create Operation
preFlush
postFlush
Create Operation
preFlush
postFlush
Create Operation
preFlush
postFlush
First Name: Zara  Last Name: Ali  Salary: 1000
First Name: Daisy  Last Name: Das  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000
preFlush
postFlush
preFlush
Update Operation
postFlush
preFlush
postFlush
First Name: Zara  Last Name: Ali  Salary: 5000
First Name: John  Last Name: Paul  Salary: 10000
preFlush
postFlush

Если вы проверите свою таблицу EMPLOYEE, она должна иметь следующие записи: