1. Картирование наследования
Наследование является важной объектно-ориентированной особенностью. Он реализует использование кода, а также имеет отношения наследования в модели взаимоотношений. Это отношение наследства на самом деле можно рассматривать как отношения перечисления. Многие подтипы могут быть перечислены в типе. Эти подтипы образуют отношения наследования с родительским объектом. Большинство перечислений, которые могут быть перечислены, можно рассматривать как карту наследования. Следовательно, это перечисление может рассматриваться как карта наследования. Например, животные - это абстрактный класс, который является родительским классом других животных, свиней, кошек и т. Д., И они являются отношением наследования, как показано на рисунке ниже:
Это отображение наследования будет генерировать таблицу после того, как она будет преобразована в реляционную модель. Итак, как эта таблица различает эти два типа? Используйте реляционные поля, вам необходимо добавить поля типа в таблицу и использовать ключевые слова, чтобы указать тип объекта. Следовательно, структура таблицы, соответствующая модели объекта на приведенной выше рисунке, выглядит следующим образом:
При создании структуры таблицы необходимо добавить соответствующий тип поля, поэтому вам необходимо добавить соответствующий дискриминатор карты в файл отображения. Здесь вам нужно использовать атрибут дискриминатора.
1. Файлы класса
Нет необходимости обращать внимание в файлах класса, просто обратите внимание на отношения наследования между ними при написании.
Список: код класса животных, вам нужно только добавить основные свойства.
пакет com.src.hibernate; открытый класс животное {// идентификационный номер частного INT ID; public int getId () {return id; } public void setId (int id) {this.id = id; } // Имя частного имени строки; public String getName () {return name; } public void setName (string name) {this.name = name; } // Гендерный частный логический секс; public boolean issex () {return sex; } public void setsex (логический секс) {this.sex = sex; }}Листинг 2: классы птиц и свиньи, добавляют основные свойства и наследуют классы животных.
пакет com.src.hibernate; Public Class Bird расширяет Animal {// Высота частная высота int; public int getheight () {return Height; } public void setheight (int height) {this.height = height; }} пакет com.src.hibernate; Public Class Pig расширяет Animal {// Вес частного веса; public int get -beight () {вернуть вес; } public void легкий вес (int Weew) {this.weight = Weew; }} 2. Файлы карты
Соответствующее отображение должно быть добавлено в файл отображения. В модель необходимо добавить только один файл отображения, поскольку генерируется только одна таблица, соответствующее отображение подкласса добавляется в файл отображения. Используйте тег <subclass>, и в тег добавляется значение дискриминатора. Это свойство дискриминатора указывает, какой тип написан при написании данных в базе данных, следующим образом:
<? 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> <class nelame = "com. table="t_animal"> <id name="id"> <generator//id> <!-- Add an authentication tag and must be placed after the id --> <discriminator column="type" /> <property name="name"/> <property name="sex" type="boolean"/> <subclass name="com.src.hibernate.Pig" discriminator-value="P"> <property name="weight"/> </subclass> <subclass name = "com.src.hibernate.bird" discinator-value = "b"> <name = "height"/> </subclass> </class> </hibernate mapping>
3. Результаты анализа
Сгенерированная таблица базы данных MySQL не только добавит основные атрибуты животного, но и добавит свойства свиньи и птицы. Поскольку добавленные атрибуты записываются с использованием <subclass> в файле отображения, а также добавлены соответствующие атрибуты дискриминатора, в базу данных будут добавлены соответствующие столбцы дискриминатора. Сформированная структура таблицы выглядит следующим образом:
2. Работа данных
1. Напишите данные
При выполнении операций с чтением и написанием данных вам необходимо обратить внимание на использование операций в классе.
public void testSave () {session = null; try {// Создать сеанс объекта сеанса = hibernateutils.getsession (); // Открыть сеанс транзакции.beginTransaction (); Свинья = новая свинья (); PIG.SetName («Маленькая свинья»); pig.setsex (true); Pig.Setweight (200); Session.save (свинья); Птица птица = новая птица (); Bird.SetName ("Xiaoniao"); bird.setsex (true); Bird.setheight (100); Session.save (птица); session.getTransaction (). Commit (); } catch (Exception e) {e.printstackTrace (); session.getTransaction (). Rollback (); } наконец {hibernateutils.closesession (Session); }}2. Полиморфный запрос-get и hql
Базовый метод запроса требует только использования нагрузки и получения методов. Здесь мы сосредоточены на полиморфическом запросе. Полиморфный запрос означает, что Hibernate может использовать экземпляр для идентификации своего истинного типа объекта при загрузке объекта, чтобы он мог быть полиморфным запросом.
Примечание. Полиморфные запросы не поддерживают ленивую загрузку, то есть, если вы используете метод загрузки, вам необходимо установить ленивую загрузку в False в файле отображения.
3. Загрузка задержки загрузки
Нагрузка поддерживает ленивую загрузку. При загрузке объектов это фактически генерирует прокси -сервер. Поэтому при использовании полиморфных запросов вам нужно установить ленивую загрузку в False в файле отображения следующим образом:
<? 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> <class nelame = "com. Таблица = "t_animal" lazy = "false"> <id name = "id"> <генератор // id> <!-Добавить тег аутентификации и должен быть помещен после идентификатора-> <discinator column = "type"/> <name = "name"/> <name = "sex" type = "boolean"/> <subclass name = "com.src.iber. name = "Wews"/> </subclass> <subclass name = "com.src.hibernate.bird" discinator-value = "b"> <свойство name = "height"/> </subclass> </class> </hibernate-mapping>
Метод загрузки загрузки, используя загрузку для загрузки, этот пример поддерживает полиморфные запросы и устанавливает задержку нагрузки в FALSE в файле конфигурации, поэтому метод загрузки можно использовать здесь для загрузки и получения соответствующего класса объекта.
public void testload () {session session = null; try {session = hibernateutils.getSession (); session.beginTransaction (); Животное ani = (животное) сеанс. Загрузка (Animal.class, 1); System.out.println (ani.getName ()); // Поскольку нагрузка поддерживает ленивый по умолчанию, мы видим прокси животного // SO, экземпляр не может идентифицировать свинью // истинного типа, поэтому нагрузка не поддерживает полиморфический запрос в этом случае, если (экземпляр свиньи ani) {System.out.println («Я - свинья!»); } else {System.out.println («Я не свинья!»); } session.getTransaction (). Commit (); } catch (Exception e) {e.printstackTrace (); session.getTransaction (). Rollback (); } наконец {hibernateutils.closesession (Session); }} 4.HQL Запрос
HQL поддерживает полиморфные запросы, которые в основном связаны с тем, что запрос является реальным объектом и не возвращает прокси. Поэтому HQL поддерживает полиморфные запросы. Кроме того, при запросе вам необходимо обратить внимание на не использовать имена таблиц в операторе запроса, а на использование имен классов. Hibernate отобразит его с соответствующим именем таблицы в соответствии с именем класса, следующим образом:
public void testload5 () {Session Session = null; try {session = hibernateutils.getSession (); session.beginTransaction (); Список <Animal> list = session.createquery ("from Animal"). List (); for (iterator iter = list.iterator (); iter.hasnext ();) {животное a = (животное) iter.next (); if (экземпляр свиньи) {System.out.println («Я свинья!»); } else {System.out.println ("Я не свинья!"); }} session.getTransaction (). Commit (); } catch (Exception e) {e.printstackTrace (); session.getTransaction (). Rollback (); } наконец {hibernateutils.closesession (Session); }}Результаты запроса:
Hibernate: выберите Animal0_ID как id0_, Animal0_.name As name0_, Animal0_.sex As Sex0_, Animal0_. Веса как Weight0_, Animal0_. Я не свинья! Я поросят! Я не свинья!
3. Три стратегии для картирования наследования
1. Таблица за иерархию класса
Предположим, что у нас есть платеж в интерфейс и несколько классов реализации: CreditCardPayment, CashPayment и ChequePayment. Тогда код отображения «таблицы на класс иерархии» заключается в следующем:
<class name="Payment" table="PAYMENT"> <id name="id" type="long" column="PAYMENT_ID"> <generator/> </id> <discriminator column="PAYMENT_TYPE" type="string"/> <property name="amount" column="AMOUNT"/> ... <subclass name="CreditCardPayment" discriminator-value="CREDIT"> <property name="creditCardType" column = "cctype"/> ... </subclass> <subclass name = "cashpayment" discinator-value = "cash"> ... </subclass> <subclass name = "chequepayment" discinator-value = "check"> ... </subclass> </class>
Для принятия этой стратегии необходим только одна таблица. Он имеет большое ограничение: требуется, чтобы поля, определенные подклассами, такие как CCTYPE, не могли иметь не-нулевые ограничения.
2. Одна таблица на подкласс
Для классов в приведенном выше примере принята стратегия отображения «Одна таблица на подкласс», и код заключается в следующем:
<class name = "платеж" таблица = "платеж"> <id name = "id" type = "long" column = "платеж_ид"> <generator/> </id> <name = "summe" column = "/> ... <kined-subclass name =" creditcardpayment "table =" credit_payment "> <ceo Column =" wather_id "/> ... </joined-subclascclass> </> </> </joined-subclass> </> </> </joined-subclass <> name = "cashPayment" table = "cash_payment"> <ключ Column = "платеж_ид"/> <name = "creditcardtype" column = "cctype"/> ... </kined-subclass> <joined-subclass name = "chequepayment" table = "cheque_payment"> <-keo clobne_de_dias> ... </joined-subclisment>
Требуются четыре таблицы. Три таблицы подклассов связаны с таблицей суперкласса с помощью первичных ключей (поэтому модель взаимосвязи на самом деле является ассоциацией один на один).
3. Каждый подкласс имеет таблицу (таблица на подкласс) и используйте дискриминатор
Обратите внимание, что для стратегии отображения «Одна таблица на подкласс» реализация Hibernate не требует поля дискриминатора, в то время как другие инструменты объекта/реляционного отображения используют метод реализации, отличный от Hibernate, который требует колонки дискриминатора типа в таблице SuperClass. Метод, принятый Hibernate, труднее реализовать, но с точки зрения отношений (базы данных) это более правильно. Если вы готовы использовать стратегию «One Table на подкласс» с областями различения, вы можете использовать <subclass> с <соединением> следующим образом:
<class name = "платеж" таблица = "платеж"> <id name = "id" type = "long" column = "платеж_ид"> <generator/> </id> <discinator column = "платеж_type" type = "string"/> <property name = "cumber" cumply "/> ... <subclass name =" CreditCardpayment "discinator-value =" intail ">" intail ">" intail ">" intail ">" intail ">" intail ">" intail ">" intail ">" intail ">" name = "CreditCardType" colun = "cctype"/> ... </join> </subclass> <subclass name = "cashpayment" discinator-value = "cash"> <join table = "cash_payment"> ... </joint> </subclass> <subclass name = "Chequepayment" discinator-value = "joina_peque_peque =" join_peque = "join_peque =" joina_peque = "joina_peque_peque =" joina_peque_peque. fetch = "select"> ... </join> </subclass> </class> </class>
Необязательное объявление fetch = "select" используется, чтобы сообщить Hibernate, что при запросе суперклассов не используйте внешнее соединение, чтобы получить данные подкласса Chequpayment.