Configuration, Session и SessionFactory

Ниже будет приведено несколько вариантов конфигурирования Hibernate. Конфигурация или отображение (mapping) обычно осуществляется один раз
в течение работы приложения. Конкретная конфигурация содержится в объекте класса net.sf.hibernate.cfg.Configuration.

private Configuration createConfiguration()

throws ClassNotFoundException, MappingException {

Configuration configuration =

new Configuration() .addClass(Class.forName("courses.hiber.Course"))

.addClass(Class.forName("courses.hiber.Student"));

return configuration;

}

Этот метод создает новую конфигурацию и добавляет в нее классы courses.hiber.Course и courses.hiber.Student(данное добавление необходимо только в том случае, если mapping-файлы не были указаны в конфигурационном файле Hibernate). Hibernate ищет mapping по принципу, указанному выше. В конфигурацию могли быть также добавлены другие источники mapping, например поток, jar-файл, org.dom4j.Document. Метод addClass() возвращает объект Configuration, поэтому он вызывается несколько раз подряд. Далее добавляется в приложение метод, генерирующий по конфигурации таблицы в базе данных.

Hibernate содержит консольное приложение для генерации скриптов. В приведенном ниже коде объект класса SchemaExport генерирует таблицы базы данных по настроенному mapping и заданным свойствам, записывает текст
в файл (c:/temp/courses_script.sql) и выполняет сгенерированный SQL-код.

private void generateAndExecuteCreationScript(Configuration configuration, Properties properties) throws HibernateException {

SchemaExport export = new SchemaExport(configuration, properties);

export.setOutputFile("c:\\temp\\courses_script.sql") .create(true, true);

}

В методе create(true, true) генерируется script-текст для создания таблиц и посылается на консоль (определяется первым параметром – true), и на его основе создаются таблицы в базе данных (второй параметр – true).

Session – это интерфейс, используемый для сохранения в базу данных и восстановления из нее объектов классов Course и Student. SessionFactory – потокобезопасный, неизменяемый кэш откомпилированных mapping для одной базы данных, фабрика для создания объектов Session.

1. Создается объект SessionFactory

SessionFactory factory = new Configuration() .configure().buildSessionFactory();

Метод configure()класса Configuration заносит информацию
в объект Configuration из конфигурационного файла Hibernate;

2. Создается сессия

Session session = factory.openSession();

3. Извлекаются все строки из таблиц course и student. Текст запросов
и команд пишется на Hibernate-диалекте. Он похож на SQL, только в качестве сущностей-носителей данных выступают классы, а не таблицы.

List courses = session.find("from Course");

List students = session.find("from Student");

4. В конце обращения сессия закрывается.

session.close();

Интерфейс net.sf.hibernate.SessionFactoryсодержит ряд необходимых методов:

openSession() – создает соединение с базой данных и открывает сессию. В качестве параметра может быть передано и соединение, тогда будет создана сессия по существующему соединению;

close() – уничтожение SessionFactory и освобождение всех ресурсов, используемых объектом.

Интерфейс net.sf.hibernate.Session– однопоточный, короткоживущий объект, являющийся посредником между приложением и хранилищем долгоживущих объектов, используется для навигации по объектному графу или для поиска объектов по идентификатору. По сути, является классом-оболочкой вокруг JDBC-соединения. В то же время представляет собой фабрику для объектов Transaction.

load(Class theClass, Serializable id) – возвращает объект данного класса с указанным идентификатором;

load(Object object, Serializable id) – загружает постоянное состояние объекта с указанным идентификатором в объект, указатель которого был передан;

save(Object object [, Serializable id]) – сохраняет переданный объект. Если передан идентификатор, то использует его;

update(Object object [, Serializable id]) – обновляет постоянный объект по идентификатору объекта, а если передан идентификатор, то обновляет объект с указанным идентификатором;

saveOrUpdate(Object object) – в зависимости от значения идентификатора сохраняет или обновляет объект;

get(Class class, Serializable id) – возвращает объект дан­ного класса, с указанным идентификатором или null, если такого объекта нет;

delete(Object object) – удаляет объект из базы данных;

delete(String query) – удаляет все объекты, полученные по запросу. Возможен и вызов запроса с параметрами delete(String query,
Object[] objects, Type[] types)
;

Transaction beginTransaction() – начинает единицу работы
и возвращает ассоциированную транзакцию.

Для осуществления запросов используется экземпляр интерфейсаorg.hibernate.Query. Получить его можно с помощью объекта Session:

session.createQuery(“from Company”)

ИнтерфейсQuery имеет следующие методы:

list() -выполняет запрос, результат возвращается в коллекции List;

session.createQuery(“from Company”).list();

executeUpdate() – для выполнения удалений, изменений, применяемых к многочисленным объектам;

session.createQuery(“delete from Company where status =’closed’”).executeUpdate();

setString(int index, String value) , setDate()и т. д. –
устанавливает параметр в запрос по индексу;

session.createQuery(“delete from Company where status =?”).setString(0, ‘closed’).executeUpdate();

также можно установить параметр по имени:

session.createQuery(“delete from Company where status =:stat”).setString(‘stat’, ‘closed’).executeUpdate();

iterate() - возвращает Iterator по результатам запроса

Iterator it = createQuery(“from Company”).iterate();

Долгоживущие Объекты и Коллекции (Persistent Objects and Collections) – это однопоточные, короткоживущие объекты, содержащие сохраняемое состояние
и бизнес-функции. Это могут быть обычные JavaBean/POJO (Plain Old Java Objects) объекты, их отличительная особенность – это то, что они ассоциированы с одной сессией (Session). Как только их сессия закрыта, эти объекты становятся отсоединенными и свободными для использования на любом уровне приложения, например, непосредственно как объекты передачи данных на уровень представления и с него.

Временные Объекты и Коллекции (Transient Objects and Collections) – это экземпляры долгоживущих классов, которые в данный момент не ассоциированы
с сессией (Session). Это могут быть объекты, созданные приложением и в данный момент еще не переведенные в долгоживущее состояние.

Транзакция net.sf.hibernate.Transaction – однопоточный, короткоживущий объект, используемый приложением для указания атомарной единицы выполняемой работы. Он абстрагирует приложение от нижележащих JDBC, JTA или CORBA транзакций. В некоторых случаях одна сессия (Session) может породить несколько транзакций:

commit() – фиксирует транзакцию базы данных;

rollback() – принуждает транзакцию возвращаться обратно.

Интерфейс net.sf.hibernate.connection.ConnectionProvider –поставщик соединений, фабрика и пул для JDBC-соединений. Абстрагирует приложение от нижележащих объектов Datasource или DriverManager. Внутренний объект Hibernate недоступен для приложения, но может быть расширен или реализован разработчиком. Методы:

close() – освобождает все ресурсы, занимаемые поставщиком соединения;

closeConnection(Connection conn) – закрывает используемое соединение;

configure(Properties props) – инициализирует поставщика соединений из переданных свойств.

Фабрика транзакций net.sf.hibernate.TransactionFactory – фабрика для экземпляров класса Transaction. Внутренний объект Hibernate недоступен для приложения, но также может быть расширен или реализован разработчиком.

beginTransaction(SessionImplementor session) – начинает транзакцию и возвращает ее объект.

Простейшее применение объявленных выше классов при добавлении
в сервлет реализаций методов generateAndExecuteCreationScript()
и createProperties()выглядит следующим образом:

/* пример # 5: простейшее применение hibernate : MainServlet.java */

package courses.servlet;

import net.sf.hibernate.cfg.Configuration;

import net.sf.hibernate.tool.hbm2ddl.SchemaExport;

import net.sf.hibernate.MappingException;

import net.sf.hibernate.HibernateException;

import net.sf.hibernate.Session;

import net.sf.hibernate.SessionFactory;

 

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.ServletException;

import java.io.IOException;

import java.util.List;

import java.util.Properties;

 

public class MainServlet extends HttpServlet {

public static SessionFactory factory;

static{

factory =