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 =