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б). |