Pull to refresh

Документация разработчика Hibernate – Глава I. Доступ к базе данных

Reading time13 min
Views60K
Представляю вашему вниманию перевод первой главы официальной документации Hibernate.

Перевод статьи актуален для версии Hibernate 4.2.19.Final

Cледующая глава — Документация разработчика Hibernate – Глава II. Транзакции и контроль многопоточности

Содержание
&nbspПредисловие
&nbsp1. Доступ к базе данных
&nbsp&nbsp1.1. Подключение
&nbsp&nbsp&nbsp1.1.1. Конфигурация
&nbsp&nbsp&nbsp1.1.2. Получение JDBC-соединения
&nbsp&nbsp1.2. Пулинг соединений (Connection pooling)
&nbsp&nbsp&nbsp1.2.1. Пулинг с помощью с3p0
&nbsp&nbsp&nbsp1.2.2. Пулинг с помощью Proxool
&nbsp&nbsp&nbsp1.2.3. Получение соединений от сервера приложений, через JNDI
&nbsp&nbsp&nbsp1.2.4. Прочее по конфигурации соединений
&nbsp&nbsp&nbsp1.2.5. Необязательные свойства конфигурации
&nbsp&nbsp1.3. Диалекты
&nbsp&nbsp&nbsp1.3.1. Указание диалекта для использования
&nbsp&nbsp&nbsp1.3.2. Разрешение диалекта
&nbsp&nbsp1.4. Автоматическая генерация схемы при помощи Schema Export
&nbsp&nbsp&nbsp1.4.1. Кастомизация файлов маппинга (Customizing the mapping files)
&nbsp&nbsp&nbsp1.4.2. Запуск инструмента SchemaExport

Предисловие


Работа как с объектно-ориентированным ПО, так и с реляционными базами данных (далее БД, прим.перев.) может быть весьма обременительной и затратной с точки зрения потраченного времени. Затраты на разработку существенно выше из-за несовпадения парадигм представления данных в объектах и реляционных БД. Hibernate является решением т.н. объектно-реляционного проецирования для Java. Термин объектно-реляционного проецирования отноcится к технике проецирования (маппинга) данных из объектной модели представления к реляционной модели представления (и наоборот). См. en.wikipedia.org/wiki/Object-relational_mapping для более подробного ознакомления.

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


Hibernate не только заботится о проецировании Java-классов в таблицы БД (а также проецировании базовых типов Java к типам SQL), но и предоставляет механизмы формирования запросов и выборок данных. Он может существенно снизить время на разработку, которая в старом стиле велась путем ручной работы с данными с использованием SQL и JDBC. Главная цель архитектурного дизайна Hibernate – избавление разработчика от ежедневных задач работы с данными БД, путем избавления от нужд написания собственной логики работы с данными через SQL и JDBC. Однако, в отличие от других persistence-решений, Hibernate не скрывает от вас возможность использовать всю мощь SQL, и гарантирует, что ваши вложения в реляционные технологии и знания по-прежнему имеют силу.
Hibernate может быть не лучшим решением для приложений, хранящих всю свою бизнес-логику в хранимых процедурах, оно скорее подходит для объектно-ориентированных моделей и логики в среднем (бизнес) слое приложения, написанном на Java. Однако, Hibernate совершенно точно может помочь вам избавиться или инкапсулировать логику специфического SQL-кода, а также справиться с повседневными задачами трансляции результатов ваших запросов из табличного представления в граф объектов.

1. Доступ к базе данных


1.1. Подключение


Hibernate соединяется с базой от имени вашего приложения. Соединение может осуществляться через различного рода механизмы, а именно:
  • Встроенный пул соединений
  • javax.sql.DataSource
  • Пулы соединений, также можно использовать сторонние открытые решения для пулов:
    • c3p0
    • proxool
  • Собственноручно созданные приложением JDBC-соединения. Это нерекомендуемый подход и единственная причина его использования – работа с устаревшим (legacy) окружением.

Важно
Встроенный пул соединений не предназначен для работы в “боевом” окружении.

Hibernate получает JDBC-соединения по мере необходимости через интерфейс org.hibernate.service.jdbc.connections.spi.ConnectionProvider. Приложения могут также предоставлять свои реализации интерфейса org.hibernate.service.jdbc.connections.spi.ConnectionProvider для определения кастомного подхода к предоставлению соединений Hibernate’у. (Из другого пула соединений, например)

1.1.1. Конфигурация


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

Пример 1.1. hibernate.properties для пула соединений c3p0

hibernate.connection.driver_class = org.postgresql.Driver
hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
hibernate.connection.username = myuser
hibernate.connection.password = secret
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
hibernate.dialect = org.hibernate.dialect.PostgreSQL82Dialect

Пример 1.2. hibernate.cfg.xml для соединения к встраиваемой базе данных HSQL

<?xml version='1.0' encoding='utf-8'?>

<hibernate-configuration
        xmlns="http://www.hibernate.org/xsd/hibernate-configuration"
        xsi:schemaLocation="http://www.hibernate.org/xsd/hibernate-configuration hibernate-configuration-4.0.xsd"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <session-factory>
    <!-- Database connection settings -->
    <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
    <property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
    <property name="connection.username">sa</property>
    <property name="connection.password"></property>

    <!-- JDBC connection pool (use the built-in) -->
    <property name="connection.pool_size">1</property>

    <!-- SQL dialect -->
    <property name="dialect">org.hibernate.dialect.HSQLDialect</property>

    <!-- Enable Hibernate's automatic session context management -->
    <property name="current_session_context_class">thread</property>

    <!-- Disable the second-level cache  -->
    <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

    <!-- Echo all executed SQL to stdout -->
    <property name="show_sql">true</property>

    <!-- Drop and re-create the database schema on startup -->
    <property name="hbm2ddl.auto">update</property>
    <mapping resource="org/hibernate/tutorial/domain/Event.hbm.xml"/>
  </session-factory>
</hibernate-configuration>


1.1.1.1. Программная конфигурация


Экземпляр объекта org.hibernate.cfg.Configuration представляет полный набор типов маппингов на базу данных. Объект org.hibernate.cfg.Configuration создает иммутабельный объект org.hibernate.SessionFactory, и компилирует маппинги из различных XML-файлов. Вы можете указать файлы для маппинга напрямую, или Hibernate может найти их за вас.

Пример 1.3. Указание файлов для маппинга напрямую

Вы можете получить объект org.hibernate.cfg.Configuration, cоздав его и указав XML-документы для маппинга напрямую. Если файлы для маппинга находятся в classpath, используйте метод addResource().

Configuration cfg = new Configuration()
    .addResource("Item.hbm.xml")
    .addResource("Bid.hbm.xml");


Пример 1.4. Hibernate находит файлы за вас

Метод addClass() указывает Hibernate искать mapping-файлы через classpath, основываясь на имени класса, при этом избавляя вас от необходимости указывать имена файлов самому. В следующем примере, он ищет org/hibernate/auction/Item.hbm.xml и org/hibernate/auction/Bid.hbm.xml.

Configuration cfg = new Configuration()
    .addClass(org.hibernate.auction.Item.class)
    .addClass(org.hibernate.auction.Bid.class);


Пример 1.5. Указание свойств конфигурации

Configuration cfg = new Configuration()
    .addClass(org.hibernate.auction.Item.class)
    .addClass(org.hibernate.auction.Bid.class)
    .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
    .setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
    .setProperty("hibernate.order_updates", "true");


Другие способы программной конфигурации Hibernate
  • Передача экземпляра java.util.Properties в Configuration.setProperties().
  • Установка системного свойства, используя java -Dproperty=value


1.1.2. Получение JDBC-соединения


После того, как вы сконфигурируете Основные jdbc-свойства Hibernate, вы можете использовать метод openSession класса org.hibernate.SessionFactory для открытия сессий. Сессии откроют JDBC-cоединения по требованию, основываясь на предоставленной конфигурации.

Пример 1.6. Открытие сессии

Session session = sessions.openSession();

Основные jdbc-cвойства Hibernate
  • hibernate.connection.driver_class
  • hibernate.connection.url
  • hibernate.connection.username
  • hibernate.connection.password
  • hibernate.connection.pool_size


1.2. Пулинг соединений (Connection pooling)


Внутренний алгоритм пулинга соединений в Hibernate довольно рудиментарен, и нужен, по большей части, для разработки и тестирования. Используйте сторонние (3rd party) пулы для лучшей производительности и стабильности. Для использования 3rd party пула, замените значение свойства hibernate.connection.pool_size на соответствующие специфике вашего выбранного пула. Это отключит использование встроенного пула Hibernate.

1.2.1. Пулинг с помощью c3p0


C3P0 – опенсорсный пул JDBC-соединений, распространяемый вместе с Hibernate в директории lib/. Hibernate будет использовать свой собственный org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider для пулинга соединений, при настройке свойств hibernate.c3p0.*

Важные конфигурационные свойства для c3p0
  • hibernate.c3p0.min_size
  • hibernate.c3p0.max_size
  • hibernate.c3p0.timeout
  • hibernate.c3p0.max_statements


1.2.2. Пулинг с помощью Proxool


Proxool — другой опенсорсный пул, распространяемый вместе с Hibernate в директории lib/. Hibernate будет использовать свой собственный org.hibernate.service.jdbc.connections.internal.ProxoolConnectionProvider для пулинга соединений при соответствующей настройке hibernate.proxool.*. В отличие от c3p0, proxool требует некоторых дополнительных параметров настройки, которые описаны в документации, доступной на proxool.sourceforge.net/configure.html.

Таблица 1.1. Важные конфигурационные свойства для пула соединений Proxool
Свойство Описание
hibernate.proxool.xml Сконфигурируйте провайдер Proxool, используя указанный файл XML (.xml добавляется автоматически)
hibernate.proxool.properties Сконфигурируйте провайдер Proxool, используя указанный property-файл (.properties добавляется автоматически)
hibernate.proxool.existing_pool Конфигурировать ли провайдер Proxool из существующего пула
hibernate.proxool.pool_alias Псевдоним пула Proxool. Необходим.

1.2.3. Получение соединений от сервера приложений, через JNDI


Для использования Hibernate внутри сервера приложений, настройте Hibernate для получения соединений от javax.sql.Datasource, зарегистрированном в JNDI, установив по крайней мере одно из следующих свойств:
Важные свойства для источников данных JNDI
  • hibernate.connection.datasource (необходимо)
  • hibernate.jndi.url
  • hibernate.jndi.class
  • hibernate.connection.username
  • hibernate.connection.password

JDBC-соединения, полученные из источника данных JNDI, автоматически участвуют в container-managed транзакциях сервера приложений.

1.2.4. Прочее по конфигурации соединений


Вы можете передавать произвольные свойства соединения, добавляя перед ними hibernate.connection. К примеру, для указания свойства charSet используйте имя hibernate.connection.charSet.
Вы можете определить свою стратегию для получения JDBC-соединений, реализовав интерфейс org.hibernate.service.jdbc.connections.spi.ConnectionProvider, и указав вашу пользовательскую реализацию при помощи свойства hibernate.connection.provider_class

1.2.5. Необязательные свойства конфигурации


В дополнение к свойствам, перечисленным выше, Hibernate включает в себя множество других параметров. См. более подробный список на http://docs.jboss.org/hibernate/orm/4.2/devguide/en-US/html_single/.

1.3. Диалекты


Хотя SQL относительно стандартизирован, каждый поставщик СУБД использует свое подмножество поддерживаемых синтаксисов. У этого есть и другой термин, называемый диалектом. Hibernate поддерживает различные вариации диалектов через класс org.hibernate.dialect.Dialect и различные подклассы для каждого vendor-диалекта.

Таблица 1.2. Поддерживаемые диалекты СУБД


1.3.1. Указание диалекта для использования


Разработчик может вручную указать диалект для использования, указав в свойстве hibernate.dialect нужное имя подкласса org.hibernate.dialect.Dialect.

1.3.2. Разрешение диалекта


Заранее предположив, что org.hibernate.service.jdbc.connections.spi.ConnectionProvider был настроен, Hibernate попытается автоматически определить диалект, основываясь на java.sql.DatabaseMetaData получаемым из объекта java.sql.Connection, который в свою очередь достается из org.hibernate.service.jdbc.connections.spi.ConnectionProvider.
Эта функциональность предоставляется экземплярами org.hibernate.service.jdbc.dialect.spi.DialectResolver, зарегистрированными cамим фреймворком. Hibernate идет вместе со стандартным набором распознаваний. Если в вашем приложении требуются дополнительные возможности распознавания диалекта, вполне возможно зарегистрировать кастомную реализацию org.hibernate.service.jdbc.dialect.spi.DialectResolver, как показано ниже
Зарегистрированные реализации org.hibernate.service.jdbc.dialect.spi.DialectResolver добавляются во внутренний список resolverов, так что они имеют приоритет над уже ранее зарегистрированными resolver’ами, а также над стандартными.

1.4. Автоматическая генерация схемы при помощи SchemaExport


SchemaExport – утилита Hibernate, которая генерит DDL-скрипты из ваших файлов маппинга. Сгенерированная схема включает в себя ограничения ссылочной целостности (referential integrity constraints), основные и внешние ключи для сущностей и таблиц коллекций. Она также создает таблицы для последовательностей(sequences) и спроецированных id-генераторов (identity generators).
Важно
Вы должны указать диалект SQL через свойство hibernate.dialect, когда используете эту утилиту, так как DDL сам по себе специфичен для каждого вендора. См подробности в Секции 1.3, “Диалекты”.

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

1.4.1. Кастомизация файлов маппинга (Customizing the mapping files)


Hibernate предоставляет ряд элементов и атрибутов для ваших файлов маппинга. Они перечислены в Таблице 1.3, “Элементы и аттрибуты, предоставляемые для кастомизации файлов маппинга”, а логический порядок кастомизации представлен в Процедуре 1.1, “Кастомизация схемы”.

Таблица 1.3. Элементы и атрибуты, предоставляемые для кастомизации файлов маппинга
Имя Тип значения Описание
length number Длина колонки
precision number Десятичная точность колонки
scale number Десятичный масштаб колонки
not-null true или false Может ли колонка содержать null-значения
unique true или false Содержит ли колонка только уникальные значения
index string Имя многоколоночного индекса
unique-key string Имя многоколоночного ограничения на уникальность
foreign-key string Имя ограничения внешнего ключа, генерируемое для ассоциаций.
Это относится к &ltone-to-one&gt, &ltmany-to-one&gt, &ltkey&gt, и &ltmany-to-many&gt элементам. inverse=«true» пропускаются SchemaExport.
sql-type string Переопределяет тип колонки по-умолчанию. Это относится только к элементу &ltcolumn&gt.
default string Значение по-умолчанию для колонки
check string SQL ограничения (SQL check constraint) либо на колонку, либо на таблицу

Процедура 1.1. Кастомизация схемы

1. Установка длины, точности, и масштаба элементов маппинга.

Множество элементов маппинга определяют необязательные атрибуты, такие как длина, точность, и масштаб.
<property name="zip" length="5"/>
<property name="balance" precision="12" scale="2"/>


2. Установка not-null, UNIQUE, unique-key аттрибутов.

not-null и UNIQUE атрибуты генерируют ограничения на табличные колонки.
Атрибут unique-key группирует колонки в единое ограничение по уникальности. Атрибут переопределяет имя любого сгенерированного ограничения уникальности.
<many-to-one name="bar" column="barId" not-null="true"/>
<element column="serialNumber" type="long" not-null="true" unique="true"/>

<many-to-one name="org" column="orgId" unique-key="OrgEmployeeId"/>
<property name="employeeId" unique-key="OrgEmployee"/>

3. Установка index и foreign-key аттрибутов.

Атрибут index указывает имя индекса для его создания, используя спроецированную колонку или колонки. Вы можете сгруппировать несколько колонок по одному индексу, указав в каждой из них имя одного и того же индекса.
Атрибут внешнего ключа (foreign key) переопределяет имя любого сгенерированного ограничения внешнего ключа.
<many-to-one name="bar" column="barId" foreign-key="FKFooBar"/>


4. Установка дочерних &ltcolumn&gt-элементов.

Множество элементов маппинга допускают использование дочерних &ltcolumn&gt элементов. Это бывает полезно для маппинга типов, включающих в себя несколько колонок.
<property name="name" type="my.customtypes.Name"/>
	<column name="last" not-null="true" index="bar_idx" length="30"/>
	<column name="first" not-null="true" index="bar_idx" length="20"/>
	<column name="initial"/>
</property>


5. Установка атрибута default.

Атрибут default представляет собой значение по-умолчанию для колонки. Добавьте значение к спроецированному свойству перед сохранением нового экземпляра класса.
<property name="credits" type="integer" insert="false">
	<column name="credits" default="10"/>
</property>
<version name="version" type="integer" insert="false">
	<column name="version" default="0"/>
</version>


6. Установка атрибута sql-type.
Используйте атрибут sql-type для переопределения маппинга по-умолчанию для типов Java на типы SQL.
<property name="balance" type="float">
	<column name="balance" sql-type="decimal(13,3)"/>
</property>


7. Установка атрибута check.
Используйте атрибут check для указания ограничения check.
<property name="foo" type="integer">
	<column name="foo" check="foo > 10"/>
</property>
<class name="Foo" table="foos" check="bar < 100.0">
  ...
  <property name="bar" type="float"/>
</class>


8.Добавление &ltcomment&gt элементов к вашей схеме.
Используйте элемент &ltcomment&gt для указания комментариев для сгенерированной схемы.
<class name="Customer" table="CurCust">
	<comment>Current customers only</comment>
	...
</class>


1.4.2. Запуск инструмента SchemaExport


Инструмент SchemaExport записывает DDL-скрипт в стандартный поток вывода, исполняет DDL, или и то, и другое сразу.
Пример 1.7. Синтаксис SchemaExport
java -cp hibernate_classpaths org.hibernate.tool.hbm2ddl.SchemaExport options mapping_files 

Таблица 1.4. Опции SchemaExport
Опция Описание
--quiet Не выводить скрипт в стандартный поток вывода
--drop Только удалять таблицы
--create Только создавать таблицы
--text Не экспортировать в БД
--output=my_schema.ddl Вывести скрипт в указанный файл
--naming=eg.MyNamingStrategy выбор NamingStrategy
--namingdelegator=eg.MyNamingStrategyDelegator выбор NamingStrategyDelegator
--config=hibernate.cfg.xml Чтение конфигурации Hibernate из файла XML
--properties=hibernate.properties Чтение свойств БД из указанного файла
--format Опрятное форматирование SQL
--delimiter=; Разделитель строк

Важно
Опции --naming и --namingdelegator, не должны использоваться вместе

Пример 1.8. Встраивание SchemaExport в ваше приложение

Configuration cfg = ....;
new SchemaExport(cfg).create(false, true);
Tags:
Hubs:
Total votes 22: ↑17 and ↓5+12
Comments3

Articles