410013796724260
• Webmoney
R335386147728
Z369087728698
Использование Sequence в HibernateСогласно спецификации JPA возможно 4 различных варианта программного генерирования первичного ключа или использование возможностей сервера БД (колонка auto-incremented в таблице или генератор последовательностей Sequence). Единственное, что необходимо выполнить при описании сущности, так это добавить аннотацию @GeneratedValue к первичному ключу и описать стратегию : @Id @GeneratedValue(strategy = GenerationType.ХХХХ) @Column(name = "id", updatable = false, nullable = false) private Long id; В данной статье будет рассмотрен вопрос генерирования целочисленного идентификатора (первичного ключа) с помощью Sequence в Hibernate. В качестве подопытной базы данных возьмем Oracle и подготовим всё необходимое для эксперимента. Начнем с базы данных : создадим таблицу USERS и генератор последовательностей SEQ_USER. SQL-скрипт создания Tablecreate table USERS ( id Integer not null, login varchar2 (16) null, name varchar2 (64) null, data timestamp default SYSDATE, CONSTRAINT PK_USERID PRIMARY KEY (id) ); SQL-скрипт создания SequenceКак создавать и работать с генераторами последовательностей Sequence подробно представлено здесь. create sequence SEQ_USER minvalue 1 start with 5 increment by 1 cache 5; Проект тестирования Sequence и HibernateПосле того, как объекты БД созданы, создадим проект hibernate-seq, в котором будет генерировать первичный ключ с использованием последовательности SEQ_USER и вносить записи в таблицу USERS. На следующем скриншоте представлена структура проекта в среде разработки Eclipse. В проекте необходимо определить файл конфигурации hibernate.cfg.xml и сущность/класс User. В модуле HibernateExample будем тестировать наши настройки. Все необходимые для работы с Oracle и hibernate библиотеки размещены в поддиректории lib.
Примечание : в демонстрационном примере hibernate был использован «файл-маппинг» person.cfg.xml сущности (Person). В данном примере вместо «файл-маппинг» user.cfg.xml сущности (User) будем использовать аннотации. Конфигурация hibernateВ конфигурационном XML-файле hibernate.cfg.xml определяются тип сервера БД (драйвер, пул подключений, диалект сервера БД, кодировка) и параметры подключения (url, login, password), а также дополнительные параметры, которые используются при работе с сервером. В качестве сервера БД определен Oracle c пулом подключений в 1 соединение; определяем истиное значение свойства "show_sql", чтобы в консоли были отображены генерируемые библиотекой Hibernate SQL-скрипты. Дополнительно устанавливаем кодировку записей UTF8. В заключении в обязательном порядке определяем маппинг сущности/класса User, иначе пример не будет работать и вызовет исключения.
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="hibernate.connection.driver_class">
oracle.jdbc.OracleDriver</property>
<property name="hibernate.connection.url">
jdbc:oracle:thin:@localhost:1521:SE</property>
<property name="hibernate.connection.username">
scott</property>
<property name="hibernate.connection.password">
tiger</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="hibernate.connection.pool_size">1</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- SQL dialect -->
<property name="hibernate.dialect">
org.hibernate.dialect.Oracle10gDialect</property>
<property name="hibernate.current_session_context_class">
thread</property>
<property name="hibernate.connection.CharSet">
utf8</property>
<property name="hibernate.connection.characterEncoding">
utf8</property>
<property name="hibernate.connection.useUnicode">
true</property>
<!-- Сущность/класс User -->
<mapping class="net.common.model.User"/>
</session-factory>
</hibernate-configuration>
Листинг класса пользователя UserПри описании сущности/класса User используем аннотации. Подробная информация об аннотациях JPA представлена здесь.
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.SequenceGenerator;
@Entity
@Table(name = "USERS")
public class User
{
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,
generator="users_seq")
@SequenceGenerator(name="users_seq",
sequenceName="SEQ_USER", allocationSize=10)
@Column(name="id", updatable=false, nullable=false)
private Integer id;
@Column (name="name", nullable=true)
private String name;
@Column (name="login")
private String login;
public User() {}
public User(Integer id, String login, String name)
{
super();
this.id = id;
this.login = login;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Описание аннотаций сущности@Table @Id @Column @GeneratedValue @SequenceGenerator Примечание : подробное описание аннотаций @OneToOne, @OneToMany, @ManyToOne, @ManyToMany при определении связей между сущностями с примерами представлено здесь. Интерфейс SessionРабота с БД в Hibernate осуществляется через объект сессии типа org.hibernate.Session, который получают из экземпляра типа org.hibernate.SessionFactory. Интерфейс org.hibernate.Session является мостом между приложением и Hibernate. С помощью сессий выполняются CRUD-операции с объектами-сущностями. Состояния объектовОбъект-сущность может находиться в одном из 3-х состояний :
Методы SessionЛюбой объект-сущность можно перевести из одного состояния в другой. Для этого в интерфейсе Session существуют следующие методы :
Объект Session кэширует у себя загруженные объекты. При загрузке объекта из БД в первую очередь проверяется кэш. Для того, чтобы удалить объект из кэша и отсоединить от сессии, используется метод session.evict(Object). Метод session.clear() применит evict() ко всем объектам в сессии. Пример использования метода удаления сущности представлен на странице описания языка HQL. Листинг класса тестирования HibernateExampleHibernateExample используется для тестирования процесса генерирования целочисленного идентификатора (первичного ключа) сущности User с помощью Sequence в Hibernate. Сначала создается сессия в методе createHibernateSession. При создании session устанавливается соединения с БД Oracle. Если сессия создана успешо, то выполняется метод saveUser, который определяет два объекта (user1, user2), открывает транзакцию и сохраняет объекты в БД. Для сохранения объектов используются методы save; можно было бы также использовать методы saveOrUpdate. После сохранения объектов их описания выводятся в консоль.
package net.common;
import java.util.List;
import java.util.Iterator;
import net.common.model.User;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
public class HibernateExample
{
private Session session = null;
//---------------------------------------------------------------
private Session createHibernateSession()
{
SessionFactory sf = null;
ServiceRegistry srvc = null;
try {
Configuration conf = new Configuration();
conf.configure("hibernate.cfg.xml");
srvc = new StandardServiceRegistryBuilder()
.applySettings(conf.getProperties()).build();
sf = conf.buildSessionFactory(srvc);
session = sf.openSession();
System.out.println("Создание сессии");
} catch (Throwable e) {
throw new ExceptionInInitializerError(e);
}
return session;
}
//---------------------------------------------------------------
private void saveUser()
{
if (session == null)
return;
User user1 = new User();
user1.setName ("Иван");
user1.setLogin("ivan");
User user2 = new User();
user2.setName ("Сергей");
user2.setLogin("serg" );
Transaction trans = session.beginTransaction();
session.save(user1);
session.save(user2);
trans.commit();
System.out.println("user1 : " + user1.toString());
System.out.println("user2 : " + user2.toString());
}
//---------------------------------------------------------------
public HibernateExample()
{
// Создание сессии
session = createHibernateSession();
if (session != null) {
System.out.println("session is created");
// Добавление записей в таблицу
saveUser();
// Закрытие сессии
session.close();
} else {
System.out.println("session is not created");
}
}
//---------------------------------------------------------------
public static void main(String[] args)
{
new HibernateExample();
System.exit(0);
}
}
Выполнение примераПри выполнении примера информация, представленная ниже, выводится в консоль. Обратите внимание, что после завершения транзакций, т.е. после выполнения commit, значения идентификаторов id записей получают сгенерированные значения. Созданные библиотекой Hibernate SQL-скрипты также выводятся в консоль, поскольку установлен соответствующий флаг в файле конфигурации hibernate.cfg.xml.
Создание сессии
session is created
Hibernate: select SEQ_USER.nextval from dual
Hibernate: insert into USERS (login, name, id) values (?, ?, ?)
Hibernate: insert into USERS (login, name, id) values (?, ?, ?)
user1 : User {id = 50, login = 'ivan, name = 'Иван'}
user2 : User {id = 51, login = 'serg, name = 'Сергей'}
Скачать примерИсходный код примера в виде проекта Eclipse hibernate-sequence.zip, включающий все необходимые библиотеки hibernate, можно скачать здесь (7.61 Mб). |
