КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Архитектура Hibernate
Лекция 9 Основы ORM на примере Hibernate Объектные СУБД Объектные СУБД, получив распространение в середине 1990-ых годов, так и не вышли за рамки ограниченного применения в определённых сферах. И по прежнему являются скорее экзотикой в большинстве промышленных сред. Объектные СУБД, с помощью метаинформации для целевого языка программирования (например C++ или Java) позволяют прозрачным образом работать с графом объектов, находиться ли часть графа объектов в памяти или нет. Кроме того, в отличие от сериализации, данный подход предоставляет развитый язык запросов, этот язык, позволяет манипулировать и искать объекты не только в памяти но и на внешних носителях, что конечно же открывает возможность к хранению огромных графов объектов, не опасаясь исчерпать лимит ОП. Другой интересной особенностью, предоставляемой объектными СУБД, является поддержка концепции сохранение по доступности (persistence by reachability), своего рода аналог сборщика мусора (garbage collector), но работающего для всего графа объекта, в том числе тех его частей, которые храняться на внешних носителях. Таким образом, объект сохраняется в БД если к нему можно получить доступ по ссылкам из других объектов. Если ссылки на какой либо объект теряются (ставятся в null), объект выходит из области видимости (становиться недостижимым) и автоматически удаляется из БД. В технологии Java, наиболее близким по смыслу Объектным СУБД является стандарт JDO (Java Data Object), который соответствует многим стандартам на Объектные СУБД, определяемым ODMG (Object Data Management Group).
Hibernate является свободно распространяемой реализацией ORM с открытым исходным кодом. С точки зрения разработчика Hibernate предстаёт в виде набора интерфейсов, которые предоставляют базовые службы для:
Кроме того, Hibernate определяет формат XML файла для задания отображения класса (в объектной модели) на таблицу (или несколько таблиц) вреляционной модели. При этом, разработчику не требуется менять структуру классов, представляющую модель предметной области. Это является несомненным плюсом, так как классы отражащие предметную область (domain model classes) могут использоваться без Hibernate, так как, вообще говоря, могут не содержать никаких ссылок на классы инфраструктуры Hibernate. Другими словами, классы предметной области могут являтся обычными классами в стиле JavaBeans (т.е. обладающие набором полей и get/set методов доступа к ним). Кроме того, классы могут (и вообще говоря в хорошей модели классов должны) иметь бизнес-методы, выполняющие операции специфичные для предметной области, например для класса Book модет быть определён метод borrow(), который автоматически создаёт необходимые объекты, отражающие факт заёма книги. Всё это может делаться без какого либо привлечения классов из инфраструктуры Hibernate. По окончании транзакции, Hibernate просто сохранит те объекты которые были изменены или добавлены. Рассмотрим пример. Пусть имеется класс User, содержащий поля:
Пусть класс имеет соответствующие get/set методы для этих полей. Тогда создание и получение списка пользователей будет выглядеть следующем образом: package bookstore;
import org.hibernate.cfg.Configuration; import org.hibernate.SessionFactory; import org.hibernate.Session; import org.hibernate.Transaction; import bookstore.domain.User;
import java.util.Iterator;
public class Main { public static void main(String[] args) throws Exception{ SessionFactory sessionFactory = new Configuration() .configure(“hibernate.cfg.xml”) .configure() .buildSessionFactory(); Session session = null; Transaction tx = null; try{ session = sessionFactory.openSession(); tx = session.beginTransaction(); User user = new User(); user.setFirstName(“First 1”); user.setLastName(“Last 1”); user.setAge(20); session.saveOrUpdate(user);
for(Iterator it = session.createQuery(“from User”).iterate(); it.hasNext();){ System.out.println(it.next()); }
tx.commit(); }finally{ if(session!= null){ session.flush(); session.close(); } } } }
При этом, в момент фиксации транзакции Hibernate обнаруживает что добавлены новые объекты и выполнит сгенерированные на лету запросы:
insert into BS_USER (FIRST_NAME, LAST_NAME, AGE, ID) values (?,?,?, null) call identity()
Обратите внимание, что последним запросом Hibernate получает от БД автоматически сгенерированный ID (PRIMARY KEY) пользователя, тем самым освобождая программиста от необходимости беспокоиться о генерации первичных ключей. Более того, при переходе на другую базу, например Oracle, вместо IDENTITY может быть использован механизм SEQUENCE, при этом для программиста такой переход осуществиться прозрачно. Для того чтобы Hibernate знал о том как конкретный экземпляр класса (объект) должен быть сохранён в БД ему необходимо предоставить так называемый файл маппинга:
<?xml version=”1.0”?> <!DOCTYPE hibernate-mapping PUBLIC “-//Hibernate/Hibernate Mapping DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”>
<hibernate-mapping package=”bookstore.domain”> <class name=”User” table=”BS_USER”> <id name=”id” column=”ID”> <generator class=”native”/> </id> <property name=”firstName” column=”FIRST_NAME” /> <property name=”lastName” column=”LAST_NAME” /> <property name=”age” column=”AGE” /> </class> </hibernate-mapping>
Этот файл задаёт соответствие между полями класса и колонками таблицы. Как видно из примера, огромную долю информации Hibernate получает использую механизм Reflection, что освобождает программиста от необходимости каждый раз задавать очевидные вещи. Например, Hibernate автоматически определяет типа полей и соответствующий им тип колонок в таблице. Так, поле класса “firstName” типа java.lang.String автоматически преобразуется к типу VARCHAR в нижележащей БД. (При этом, в случае использования Oracle это будет автоматическое преобразование в тип VARCHAR2). Вообще говоря, обязательным в данном файле является только имя класса, всё остальное (включая имя таблицы) Hibernate может сгенерировать автоматически. Существуют различные механизмы, которые позволяют задавать политику генерации имён таблиц и полей, например табилца должна иметь определённый префикс, называться только большими буквами, а поля вместо стиля firstName должны преобразовавыться к FIRST_NAME. Всё это можно настроить с помощью предоставляемых инструментов. Для того чтобы запустить Hibernate ему надо задать конфигурацию. Это можно сделать используя файл hibernate.cfg.xml и поместив его в корневой каталог куда указан CLASSPATH. При вызове метода new Configuration().configure() Hibernate пытается обнаружить файл с указанным именев в CLASSPATH и если надодит считывает его и строит конфигурацию. Пример конфигурационного файла приведён ниже.
<!DOCTYPE hibernate-configuration PUBLIC “-//Hibernate/Hibernate Configuration DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”>
<hibernate-configuration> <session-factory> <property name=”show_sql”>true</property> <property name=”dialect”>org.hibernate.dialect.HSQLDialect</property> <property name=”cache.provider_class”> org.hibernate.cache.HashtableCacheProvider </property> <property name=”connection.driver_class”> org.hsqldb.jdbcDriver </property> <property name=”connection.username”>sa</property> <property name=”connection.password”></property> <property name=”connection.url”> jdbc:hsqldb:hsql://localhost </property> <mapping resource=”bookstore/domain/User.hbm.xml”/> </session-factory> </hibernate-configuration>
В примере показана простейшая конфигурация для БД Hypersoniq SQL (HSQLDB). Обязательными параметрами являются параметры соединения с БД (драйвер, имя пользователя, пароль а так же строка соединения (connection string)) и так называемый «диалект» целевой БД. Диалект как раз и представляет собой тот уровень абстракции на котором происходит преобразование запросов из платформенно независимых – в зависимые и наоборот.
<to be continued>
Дата добавления: 2014-01-05; Просмотров: 1500; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |