Тарифы        13.07.2019   

Технология проведения миграции данных в крупных проектах. Что такое мэппинг

Port mapping - это переадресация принимаемых данных таким образом, чтобы данные, принимаемые на какой-то порт одного компьютера автоматически переадресовывались на какой-то другой порт другого компьютера.

На самом деле это гораздо легче технически реализовать, чем объяснить сам принцип. Это можно сравнить с солнечным зайчиком: если Вы направляете луч света в зеркало, он "автоматически" отражается и освещает какой-либо предмет. При этом если вы осветили какого-либо человека и этот человек не знает, что луч отразился от зеркала, он будет думать, что свет исходит от того места, где находится зеркало. Так же и здесь: все передаваемые Вами данные безо всяких искажений передаются на другой компьютер, который может быть расположен где угодно.

Эта технология в чем-то аналогична прокси серверу, однако она гораздо проще и гораздо менее гибкая.

Схема примерно такая же, как и при использовании прокси (можно сказать, что port mapping похож на proxy - но это будет то же. что сказать "дедушка похож на внука" - вообще-то это как раз proxy похож на port mapping):

Ваш компьютер >>> компьютер с port mapping >>> удаленный сервер.

Для чего нужен port mapping?

  1. Если в организации используется корпоративный прокси, то настроив на нем port mapping на внешний почтовый сервер (mail.ru), Вы сможете использовать любую почтовую программу изнутри корпоративной сети - и Вам не потребуется устанавливать/настраивать никаких дополнительных программ!
  2. Точно таким же образом как почтовую программу, Вы можете настроить практически любую другую программу! Лишь бы она поддерживала TCP/IP.

Разумеется это только основные способы применения port mapping. Существует еще масса видов деятельности, где он также будет весьма и весьма полезен.

Преимущества port mapping

  1. Эта система очень проста и в интернет имеется множество программ, позволяющих реализовать эту функцию;
  2. Поскольку данные передаются 100% безо всяких искажений, Вам обеспечена 100% анонимность;
  3. Если Вы используете эту систему, Вам не нужны никакие "соксификаторы" - поскольку не требуется никаких дополнительных инициализаций соединения, соединение с port mapper-ом эквивалентно соединению с удаленным компьютером.

Недостатки port mapping

  1. Эта система не отличается гибкостью. В отличие от прокси, у которого через один прокси можно подключиться на множество сайтов, через один port mapping можно подключиться только к одному серверу.
  2. Для каждого нового port mapping нужно изменять настройки на сервере, где реализована эта функция - с клиентского компьютера это недоступно.
  3. В интернете нет бесплатных port mapper-ов (ввиду их крайней ограниченности - один port mapping дает доступ только на один сервер), поэтому если Вы хотите быть действительно анонимным на своем компьютере, Вам нужно где-то иметь сервер, на котором будет установлена программа для маппинга портов - и вот уже адрес этого сервера и будет "светиться" в логах веб-сайтов.

Как работать с port mapping

Учтите, схема работы с port mapping примерно та же, что и при работе с proxy, только еще проще. Port mapping - это алиас (дополнительное имя) для компьютера, на который он настроен.

Предположим, что сделан port mapping:

192.168.1.255:1234 => www.mail.ru:80 (80-й порт - это порт web серверов)

Тогда для того, чтобы открыть сайт mail.ru, Вы можете использовать 2 способа - откройте в окошке браузера сайт:

  1. http://www.mail.ru
  2. http://192.168.1.255:1234/
    данном случае обязательно пишите http:// )

Хотелось бы заметить: если Вам нужно использовать port mapping, то Вы должны пользоваться только вторым адресом . То есть если Вы не можете подключиться к mail.ru, то Вы должны использовать только внутренний адрес (http://192.168.1.255:1234/).

Port mapping на локальном компьютере

В случае, когда у Вас делается port mapping на Вашем же компьютере, то обычно указывают:

  1. local port - локальный порт на Вашем компьютере, к которому Вы должны будете подключаться для использования port mapping. Это число может быть любым (от 1 до 65535), желательно больше 1000;
  2. remote host - тот компьютер (хост), на который указывает port mapping. Например, это может быть почтовый сервер pop.mail.ru ;
  3. remote port - порт компьютера, к которому будет происходить подключение через port mapping. Для получения почты (POP3) это обычно порт 110 , для отправки почты (SMTP) - порт 25, для web серверов (www...) - это обычно порт 80.

Так вот, в этом случае Вам нужно (настроив port mapping) подключаться не к mail.ru (и им подобным), а указать в качестве сервера Ваш же компьютер:

127.0.0.1:localport

где localport - это номер порта, заданный при настройке port mapping. Например это может быть порт 1234.

То есть если Вы сделали port mapping на web сайт, то Вам нужно писать: http://127.0.0.1:1234/

Если же Вы настраиваете почту - то в качестве почтового сервера укажите 127.0.0.1 - как для получения, так и для отправки почты. И не забудьте найти настройки номеров портов (POP3 и SMTP) в Вашем почтовом клиенте и изменить их в соответствии с Вашими же настройками в port mapping!

Хранилище данных для финансового учреждения

Хранилища данных в банковской отрасли призваны консолидировать разрозненные данные разобщённых систем и извлекать информацию из консолидированных данных. Хотя хранилище может решать проблемы консолидации данных, оно не может решить как по волшебству все проблемы, связанные с информаций. Формирование проекта по построению банковского хранилища данных и управление им требует сознательных усилий всех заинтересованных сторон.

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

1. Определение заинтересованных сторон в соответствии с бизнесом банка (розничные банковские услуги, корпоративный бизнес, кредитные карты, и т. п.).

Заинтересованные стороны должны обладать соответствующими знаниями. Для лучшего понимания хранилища данных и его потребностей для каждой отдельной бизнес-функции необходимо включать в проектную группу сотрудников как со стороны бизнеса, так и со стороны подразделения бизнес-технологии. Заинтересованные стороны должны быть вовлечены в проект с самого начала, чтобы избежать утечек информации в группах.

2. Обучающие занятия для понимания потребности в хранилище данных в банке.

Заинтересованные в проекте группы должны понимать, что хранилище данных - это репозиторий только для релевантных элементов данных, а не точная копия исходной системы. Это помогает группам решить, какие данные стоит хранить.

3. Понимание концепции моделирования данных.

Понимание принципов использования таблиц мета-данных и исторических таблиц обеспечивает уверенность проектной группы в том, что их требования будет реализованы в модели данных.

4. Коллективное выявление ландшафта исходных систем.

Следует убедиться, что каждой системе в организации уделено должное внимание, и рассмотрен вопрос о её включении в хранилище данных.

5. Выстраивание проекта вокруг базовой модели для понимания общего подхода к расширению модели данных.

Базовая модель должна покрывать основные измерения в масштабе бизнеса и давать представление о фактических данных, которые, возможно, надо хранить.

6. Мэппинг данных .

a) Мэппинг данных из источника (исходных систем в организации) в целевую структуру (модель данных хранилища).

Необходимо определить исходные системы и отношения между системами для каждого измерения в модели данных.

b) Мэппинг данных для каждой функции с членами группы со стороны бизнеса и ИТ:

Этот мэппинг может потребоваться на двух уровнях:

Прямой мэппинг из исходных систем: большинство элементов данных будут отнесены напрямую в модель данных. Здесь потребуется определить источник и наименования полей.

Производный мэппинг из исходных систем: некоторые элементы данных в модели могут потребовать применения бизнес-правил к данным исходной системы для получения точной информации. Они должны быть чётко документированы.

При мэппинге из двух и более источников следует определить отношения между этими исходными системами.

7. Определение агрегирования .

Одна из целей создания хранилища данных - это получение аналитической информации из исторических данных. Кроме того, это включает в себя построение предикативных тенденций на основе данных. Агрегация определяет слои или измерения, в разрезе которых анализируются данные. Лучше всего, если агрегации определены на основании информации (отчётов и информационных панелей), которая должна быть получена из модели данных.

8. Пропускание и именование элементов данных.

Проектные команды должны принять тот факт, что источник не всегда может предоставить все данные в рамках стандартной модели. Члены команды должны принять решение либо исключить эти элементы в модели или оставить их, но не использовать. Предпочтительный путь – это опустить нерелевантные поля. Они должны оставаться неиспользуемыми, только тогда, когда предполагается, что они могут пригодиться в будущем.

9. Декларация дальнейшего совершенствования процессов .

В то время как хранилища данных сами по себе не являются проектом по усовершенствованию процессов, они могут нести улучшение вне самого хранилища. Недостатки, замеченные в процессах или в исходных системах, должны быть отмечены и параллельно устранены. Однако, изменения, внесённые процессом, могут быть сделаны позже, и не должны затронуть проект построения хранилища данных.

10. Выравнивание версий .

Мэппинг и модели данных должны быть приняты как версии, привязанные к изменениям по мере развития проекта. Важно сформировать процесс, направленный на адаптацию к этим изменениям.

Наличие слишком большого объема данных для хранения и анализа может представлять собой проблему для каждой организации, особенно когда это приводит к противоречиям в показателях. Когда данных становится слишком много, приходится разбираться с конфликтующими данными в отчётах, выбирать между противоречивыми показателями и удалять дублированные записи. Это отнимает слишком много времени и ресурсов, особенно в крупнейших компаниях, внедривших слишком много хранилищ или витрин данных, дающих разную информацию об одинаковых бизнес-процессах или событиях.

Решать эту проблему приходится как банковским учреждениям, так и предприятиям реального сектора экономики. Обратившись к их опыту, можно почерпнуть несколько универсальных рекомендаций.

Сокращение многочисленных хранилищ данных до одного экземпляра

Компания Boeing прошла через этот процесс, начав с 12 хранилищами данных и 50 системами управления расходами, некоторые из которых имели десятки тысяч бизнес-правил. «Проблема заключалась в том, что наш IT-отдел предоставлял пользователям то, что им нужно, однако они не общались друг с другом», - говорит Билл Керли (Bill Curley) сотрудник финансового отдела Boeing. Это отсутствие интеграции являлось причиной несоответствия в отчетах.

У Boeing ушло несколько лет на консолидацию всей финансовой отчётности в единое целое. Работавшие над этой задачей члены проектной группы предпочли подход «сверху вниз» - они опросили «владельцев данных», какая информация им необходимо для выполнения работы, и внедрили стандартный словарь данных, имеющий минимум необходимых элементов. Кроме того, они разделили операционные и фактические бухгалтерские данные, необходимые для отчётов. «Нам больше не требовалось проводить оперативную информацию через нашу бухгалтерскую систему», - говорит Билл Керли.

Переход к использованию единой архитектуры данных для улучшения качества данных

Над этой задачей в течение нескольких последних лет работала компания Nike. Для этого архитектор данных компании Джеймс Ли (James Lee) устранил дублирующиеся данные, заполнил отсутствующие поля в таблицах и разобрался с серией отчётов, которые слишком долго формировались. «На пути к единой версии правды мы хотели достигнуть значительной гибкости, чтобы бизнес-подразделения могли генерировать свои отчёты без участия IT-отдела. Одной из целей была самодостаточность пользователей относительно работы с данными», - вспоминает он. Одна из наиболее часто используемых таблиц Nike содержала больше сотни столбцов. Это было чрезвычайно неэффективно с точки зрения операций ввода-вывода и использования вычислительных мощностей. Nike упростил эту сверхширокую таблицу и сократил свои модели данных до меньшего числа элементов. Этот процесс также улучшил качество данных, так как на пользователей возложили ответственности за отсутствующие, но необходимые элементы данных, и они стали более активными в их отслеживании.

Публикации

  1. Аарти Няядиш (Aarti Nyayadish). «Идеальный проект хранилища данных: 10 шагов для установления верного темпа» (Ideal Banking Data Warehousing project: 10 steps for setting the right pace), 15 января 2013 г.
  2. Дэвид Стром (David Strom). «Как справиться с избытком данных: как это сделали Boeing, Nike и другие» (Coping with Too Much Data: How Boeing, Nike and Others Did It), 23 октября 2012 г.

Замеппленые классы должны декларировать столбец первичного ключа в таблице базы данных. Большинство классов также должны описывать собственные свойства в стиле JavaBeans, включая уникальный идентификатор сущности. Элемент в mapping-файле определят отображение этого уникального поля на столбец таблицы, выступающий в роли основного ключа (primary key).

(5)

(1)

name (необязательный): Наименование свойства идентификатора.

(2)

type (необязательный): Имя определяющее Hibernate-тип свойства.

(3)

column (необязательно - по умолчанию имя свойства): Название колонки основного ключа.

(4)

unsaved-value (необязательно - по умолчанию null): Значени свойства идентификатора, которое обзначает, что экземпляр новый (в терминах персистентного хранилища). Отличает данный экземпляр от транзитных экземпляров, которые были загружены или сохранены в предыдущей версии.

(5)

access (необязательный - по умолчанию property): Эту стратегию Hibernate будет использовать для доступа к данному свойству объекта.

Если атрибут name не указан, предполагается, что класс не имеет свойства идентификатора.

Атрибут unsaved-value важен! Если свойство идентификатор вашего класса по умолчанию не null, вы должны установить атрибут "unsaved-value" в соответствующее значение.

Существует альтернативное объявление для доступа к унаследованным (legacy) данным c композитными ключами. Мы настойчиво не рекомендуем использовать композитные ключи в других случаях.

5.1.4.1. generator

Обязательный дочерний элемент "а определяет Java класс используемый для генерации уникальных идентификаторов экземпляров песистентных классов. При необходимости используется элемент Для передачи параметров инициализации или конфигурирации экземпляра генератора.

uid_table next_hi_value_column

Все генераторы реализуют интерфейс net.sf.hibernate.id.IdentifierGenerator. Это очень простой интерфейс; многие приложения могут использовать свою специальную реализацию генератора. Несмотря на это, Hibernate включает в себя множество встроенных генераторов. Ниже идут краткие наименования (ярлыки) для встроенных генераторов:

Increment

генерирует идентификаторы типа long, short или int, уникальные только когда другие процессы не добавляют данные в ту же таблицу. Не использовать в кластере.

identity

Поддерживает identity колонки в in DB2, MySQL, MS SQL Server, Sybase и HypersonicSQL. Тип возвращаемого идентификатора long, short или int.

sequence

Использует последовательность (sequence) в DB2, PostgreSQL, Oracle, SAP DB, McKoi или generator в Interbase. Тип возвращаемого идентификатора long, short или int.

hilo

Использует hi/lo алгоритм для эффективной генерации идентификаторов которые имеют тип long, short или int, требуют наименования таблицы и столбца (по умолчанию hibernate_unique_key и next_hi соответсвенно), как источник значений hi. Алгоритм hi/lo генерирует идентификаторы которые кникальный только для отдельный баз данных. Не используйте этот генератор для соединений через JTA или пользовательских соединений.

seqhilo

использует алгоритм hi/lo для генерации идентификаторов типа long, short или int, с использованием последовательности (sequence) базы данных.

uuid.hex

Использует 128-битный UUID алгоритм для генерации строковых идентификаторов, уникальных в пределах сети (изспользуется IP-адрес). UUID - строка длинной в 32 символа, содержащая шеснадцатеричное представление числа.

uuid.string

использует тот же UUID алгоритм, однако строка при использовании этого генератора состоит из 16 (каких-то) ANSII символов. Не использовать с PostgreSQL.

native

выбирает identity, sequence или hilo, в зависимости от возможностей используемой базы данных.

assigned

предоставляет приложению возможность самостоятельно задать идентификатор объекта перед вызовом метода save().

foreign

используется идентификатор другого, ассоциированного объекта. Обычно используется в крньюкции с оассоциацией по первичному ключу.

5.1.4.2. Алгоритм Hi/Lo

Генераторы hilo и seqhilo предоставляют две альтернативные реализации алгортма hi/lo, наиболее предпочтительного подхода для генерации идентификаторов. Первая реализация требует "специальной" таблицы в базе данных, для хранения следующего "hi" значения. Вторая реализация использует последовательность (Oracle-style), в базах данных, которые их поддерживают.

hi_value next_value 100 hi_value 100

К сожалению вы не можете использовать hilo в случае поставки своего соединения (Connection) в Hibernate, так же невозможно его использование в конфигурации, когда Hiberante использует источник данных сервера приложений, управляемый JTA. Hiberante должен иметь возможность получать "hi" значение в новой тразакции. Стандартным подходом в EJB, является использование session stateless bean для реализации алгоритма hi/lo.

5.1.4.3. Алгоритм UUID

Не пробуйте использовать uuid.string в PostgreSQL.

5.1.4.4. Последовательности и identity колонки

Вы можете использовать генератор ключей identity для баз данных с поддержкой indentity столбцов (DB2, MySQL, Sybase, MS SQL). Для баз данных поддерживающих последовательности можно использовать sequence стиль для генерации ключей. Обе эти стратегии требуют двух SQL запросов для вставки нового объекта в базу данных.

uid_sequence

Для разработки кроссплатформеннох приложений используйте стратегию native. Она будет использвать identity, sequence и hilo стратегии в зависимости от возможностей той базы данных с которой в данный момент времени работает Hibernate.

5.1.4.5. Задаваемые идентификаторы

Если вы хотите чтобы приложение само назначало идетнификаторы, вы можете использовать генератор assigned. Этот специальный генератор использует идетнификаторы которые устанавливаются приложением. Для этого приложение устанавливает идентификатор в соответсвующее свойство объекта. Будте очень внимательны при использовании этой возможности для установки ключей (в большинстве случаев это решение сигнализирует о плохом дизайне приложения).

Вследствие свойственной ему природы, сущности которые используют этот генератор, не могут быть сохранены через метод Session.saveOrUpdate(). Вместо этого вы должны явно указывать Hibernate, должен ли объект быть создан или обновлен вызовами соотвествующих методов объекта Session: save() или update().

5.1.5. composite-id

......

Для таблиц с композитными ключами вы можете отображать несколько свойств класса как свойства идентификации объекта. Элемент принимает отображения свойств при помощи дочерних элементов и .

Ваш персистентный класс должен переопределять методы equals() и hashCode() для реализации эквивалентности композитных идентификаторов. Он так же должен реализовывать интерфейс Serializable.

К сожалению, возможность задавать составные идентификаторы подразумевает то, что персистентный объект и есть идентификатор. Нет возможности для удобной обработки, чем посредством самого объекта. Вы должны создать сущность персистентного класса самостоятельно и установить его идентифицирующее свойство перед тем как выполнить загрузку load() персистентного состояния ассоциированного с данным составным идентификатором. Мы опишем более подходящий способ, где составные идентификаторы реализованы отдельным классом в разделе Раздел 7.4, «Компоненты как составные идентификаторы» . Атрибуты, которые описываются ниже, применимы только для альтернативного метода:

    name (необязательно): свойство типа копонента, которое содержит составной идентификатор (см. следующий раздел).

    class (опционально, по умолчанию тип свойства определяет через рефлексию): компонент данного класса используется как составной идентификатор (см. следующий раздел).

    unsaved-value (опционально, по умолчанию none): если установлен в any, то это указывает на то, что транзитные сущности рассматриваются как новые.

5.1.6. discriminator

Элемент необходим для полиморфной персистентности, использующей стратегию отображения table-per-class-hierarchy. Данный элемент объявляет колонку-дискриминатор, по которой определяется соответствие записи в таблице конкретному классу в иерархии. Дискриминатор может иметь один из следующих типов: string, character, integer, byte, short, boolean, yes_no, true_false.

Соответствующие значения колонки дискриминатора для каждого класса задаются в атрибуте discriminator-value для элементов и .

Атрибут force полезен только в случае, если таблица содержит записи с дополнительными значениями дискриминатора, которые не отображаются в персистентном классе. Обычно данный атрибут не используется.

5.1.7. version (необязательно)

Элемент отражает то, что таблица содержит записи с пометкой о версии. Это особенно полезно, если вы планируете использовать длинные транзакции (см. ниже).

(1)

column (необязательно, по умолчанию берется имя свойства): имя колонки, которая хранит номера версий.

(2)

name: Имя свойства персистентного класса.

(3)

type (необязательно, по умолчанию integer): тип свойства версии.

(4)
(5)

unsaved-value (необязательно, по умолчанию undefined): Значение свойства версии, которое указывает на то, что сущность еще не сохранена (unsaved). Не путайте несохраненные сущности от транзитных, которые были сохранены или загружены в предыдущей сессии. (undefined указывает на то, что будет использовано значение идентификатора.)

Номера версий могут быть типа long, integer, short, timestamp либо calendar.

5.1.8. timestamp (необязательно)

Элемент указывает на то, что таблица содержит записи промаркированные временной меткой. Этот элемент выступает как альтернатива маркерам версии. Временные метки по определению менее безопасная реализация оптимистической блокировки. Тем не менее, иногда приложение использует временные метки для других целей

(1)

column (необязательно, по умолчанию используется имя свойства): имя колонки, которая содержит временную метку.

(2)

name: Имя в стиле JavaBeans типа Date или Timestamp свойства персистентного класса.

(3)

access (необязательно, по умолчанию property): стратегия, которую должен использовать Hibernate для доступа к значению свойства.

(4)

unsaved-value (необязательно, - по умолчанию null): Значение свойства времени, которое указывает на то, что сущность еще не сохранена (unsaved). Не путайте несохраненные сущности от транзитных, которые были сохранены или загружены в предыдущей сессии. (undefined указывает на то, что будет использовано значение идентификатора.)

Примечание: элемент эквивалентен элементу .

5.1.9. property

Элемент Объявляет персистентное, в стиле JavaBeans, свойство класса.

(1)

name: Имя свойства, начинается с буквы в нижнем регистре.

(2)

column (необязательно, по умолчанию подставляется название свойства): имя соответствующей колонки в таблице базы данных.

(3)

type (необязательно): название Hibernate-типа.

(4)

update, insert (необязательно, по умолчанию true) : указывает на то, что соответствующая колонка должна включаться в SQL-выражения UPDATE и/или INSERT. Установка обоих свойств в false позволяет задавать значение этого свойства либо из другого свойства, которое отображено в той же колонке/колонках, либо посредством триггера, либо другим приложением.

(5)

formula (необязательно): SQL-выражение, которое вычисляет значение свойства. Вычисляемые поля не должны отображаться в колонку таблиц базы данных.

(6)

access (необязательно, по умолчанию property): стратегия, которую Hibernate должен использовать для доступа к значению свойства.

значение свойства type может быть одним из следующих:

    Имя базового типа Hibernate (например, integer, string, character, date, timestamp, float, binary, serializable, object, blob).

    Имя Java-класса (например, int, float, char, java.lang.String, java.util.Date, java.lang.Integer, java.sql.Clob).

    Имя производного от PersistentEnum класса (например, eg.Color).

    Имя сериализуемого Java-класса.

    Имя пользовательского класса (например, com.illflow.type.MyCustomType).

Если вы не указываете значение свойства type, Hibernate будет использовать рефлексию для указанного свойства для подбора соответствующего Hibernate типа. Hibernate попытается определить имя класса возвращаемого свойства методом get() используя правила 2, 3, 4 в этом порядке. Тем не менее, этого не всегда бывает достаточно. В некоторых случаях вам все же необходимо указать атрибут type. (Например для различия между Hibernate.DATE и Hibernate.TIMESTAMP, либо для указания пользовательского типа.)

Атрибут access позволяет управлять задавать Hibernate метод доступа к полю во время исполнения. По умолчанию Hibernate вызывает методы get/set для доступа к полю. Если вы задаете access="field", то Hibernate будет обходить методы get/set и обращаться к полю напрямую, используя рефлексию. Вы можете указать вашу собственную стратегию для доступа указав класс, который реализует интерфейс net.sf.hibernate.property.PropertyAccessor.

5.1.10. many-to-one

Обычная связь с другим персистентным классов объявляется используя элемент many-to-one. В реляционных терминах это ассоциация многих к одному. В действительности это просто ссылка на объект.

(1)

name: Имя свойства.

(2)

column (необязательно): Имя колонки.

(3)

class (необязательно - по умолчанию тип поля определяется через рефлексию): Имя ассоциированного класса.

(4)

cascade (необязательно): Определяет, какая операция будет выполняться каскадом от родительского объекта к ассоциированному.

(5)
(6)

update, insert (необязательно - по умолчанию true) определяет то, что отображаемые колонки будут включены в SQL-запросы UPDATE и/или INSERT. Установка обоих свойств в false позволяет задавать значение этого свойства либо из другого свойства, которое отображено в той же колонке/колонках, либо посредством триггера, либо другим приложением.

(7)

property-ref: (необязательно) Имя ключевого свойства ассоциированного класса. По этому свойству будет происходить связывание (join). Если не указано, то используется первичный ключ ассоциированного класса.

(8)

access (необязательно - по умолчанию property): Стратегия, которую использует Hibernate для доступа к значению данного поля.

Атрибут cascade может принимать следующие значения: all, save-update, delete, none. Установка значения отличного от none повлечет определенные операции над ассоциированным (дочерним) объектом. См ниже "Жизненный цикл объектов".

Атрибут outer-join может принимать три следующих значения:

    auto (по умолчанию) извлекает ассоциированные объекты используя outer join если ассоциированный класс не имеет прокси.

    true Всегда извлекать ассоциированные объекты используя outer join.

    false Никогда не извлекать ассоциированные объекты используя outer join.

Типичное объявление ассоциации many-to-one выглядит так

Атрибут property-ref использоваться только для связи c унаследованными данными, когда внешний ключ ссылается на уникальное значение ассоциированной таблицы отличной от первичного ключа. Это опасное реляционное решение. Например, возможно, что класс Product имеет уникальный последовательный номер, который не является первичным ключем. (Атрибут unique конролирует герерацию DDL Hibernate"ом. Генерация производится при помощи утилиты SchemaExport.)

Отображение для OrderItem может использовать:

В действительности, так делать крайне не рекомендуется.

5.1.11. one-to-one

Ассоциация "один к одному" с другим персистентным классом можно объявить, используя элемент one-to-one.

(1)

name: Имя свойства.

(2)

class (необязательно - по умолчанию определяется рефлексией исходя из типа поля): Имя ассоциированного класса.

(3)

cascade (необязательно) определяет какая операция будет выполняться каскадом от родительского объекта к ассоциированному.

(4)

constrained (необязательно) определяет то, что внешний ключ, ссылающийся на таблицу ассоциированного класса, ограничен первичным ключом этой таблицы. Эта опция влияет на порядок, в котором выполняются каскадные операции save() и delete() (а так же используется утилитой экспортирующей схему - schema export tool).

(5)

outer-join (необязательно - по умолчанию auto): Задействует извлечение ассоциированных объектов, используя объединения outer-join если опция hibernate.use_outer_join конфигурационного файла включена.

(6)

property-ref: (необязательно) Имя свойства ассоциированного класса, которое входит в первичный ключ данного класса. Если не указано, то используется первичный ключ ассоциированного класса.

(7)

access (необязательно, по умолчанию property): Стратегия, которую должен использовать Hibernate для доступа к данному полю.

Существует два вида ассоциаций "один к одному":

    связь по первичному ключу

    связь по уникальному внешнему ключу

Для организации ассоциации по первичному ключу нет надобности в дополнительных столбцах; если две записи связаны такой ассоциацией, то это значит, что две записи в двух таблицах имеют одно и то же значение первичного ключа. Следовательно, если вы хотите ассоциировать два объекта, чтобы они были связаны по первичному ключу, то вы должны убедиться в том, что их идентификаторам присвоены одинаковые значения!

Для ассоциации по первичному ключу добавьте следующее отображение для классов Employee и Person соответственно.

Теперь мы должны убедиться в том, что первичные ключи связанных записей в таблицах идентичны. Мы используем специальный генератор Hibernate foreign:

employee ...

Сохраняемому экземпляру класса Person присваивается тоже значение первичного ключа, которое присвоено экземпляру класса Employee на который ссылается свойство employee класса Person.

Как альтернативный вариант описания связи "один к одному" от Employee к Person, через уникальный внешний ключ можно использовать следующую запись:

Эта ассоциация может быть двунаправленной после добавления следующего выражения к маппингу класса Person:

5.1.12. component, dynamic-component

Элемент отображает поля вложенного объекта на колонки таблицы родительского класса. Компоненты могут в свою очередь определять свои собственные свойства, компоненты или коллекции. Смотрите "Компоненты" ниже.

(5) ........

(1)

name: Наименование свойства (ссылающегося на компонентный объект).

(2)

class (необязательно - по умолчанию тип компонента определяется используя рефлексию): Наименование класса компонента.

(3)

insert: Если установлен в true, то отображаемые поля компонента участвуют в SQL-запросах INSERT.

(4)

update: Если установлен в true, то отображаемые поля компонента участвуют в SQL-запросах UPDATE.

(5)

access (необязательно - по умолчанию property): Стратегия, которую должен использовать Hibernate при доступе к этому компоненту через родительский объект.

Вложенные тэги Отображают поля компонента в колонки таблицы.

Элемент допускает вложенный элемент Который отображает свойство компонента как обратную ссылку на родительский объект.

Элемент позволяет использовать Map как компонент, в котором имена полей соответствуют ключам Map"а.

5.1.13. subclass

И наконец, полиморфная персистентность требует объявления каждого подкласса базового класса. Для (рекомендованной) стратегии отображения table-per-class-hierarchy используется элемент .

.....

Каждый подкласс должен объявлять свои собственные персистентные поля и подклассы. Допускается наследование свойств и от базового класса. Каждый подкласс в иерархии должен определять уникальное значение discriminator-value. Если это значение не указано, то в качестве дискриминатора используется полное имя класса.

5.1.14. joined-subclass

В качестве альтернативы, подкласс, объекты которого хранятся в отдельной таблице (стратегия отображения table-per-subclass), объявляется используя элемент .

.....

Для данной стратегии отображения не требуется указывать колонку discriminator. Однако, каждый подкласс должен объявлять колонку таблицы, которая содержит идентификатор отображаемый элементом . Маппинг приведенный в начале раздела может быть переписан следующим образом:

Персистентное состояние состоит из ссылок на другие сущности и экземляры типов-значения . Значения это примитивы, коллекции, компоненты и другие неизменяемые объекты. В отличии от сущностей экземляры типов значений (в частности коллекции и компоненты) сохраняются и удаляются по доступности. Поскольку объекты типов-значений (и примитивы) сохраняются и удаляются вместе с содержащей их сущностью они не могут иметь независимую версионность. Значения не имеют так же независимой идентификатоции и, таким образом, не могут быть разделены между двумя сущностями или коллекциями.

Все типы в Hibernate, за исключением коллекций, поддерживают семантику null-указателей.

До этого момента мы использовали термин "персистентный класс" для ссылки на сущности. Мы будем продолжать делать это. Строго говоря, не все определенные пользователем классы с персистентным состоянием являются сущностями. Например, компонент - это определенный пользователем класс с семантикой типа-значения (коспоненты, являются частью сущностей их содержащих, и считаются полями этих сущностей).

5.2.2. Базовые типы-значения

Базовые типы могут быть грубо разделены следующим образом

integer, long, short, float, double, character, byte, boolean, yes_no, true_false

Мапинги примитивных Java-типов либо классов оберток на соответсвующие (зависимые от поставщика) SQL-типы колонок таблиц. boolean, yes_no и true_false являются альтернативными обозначениями для Java-типов boolean или java.lang.Boolean.

string

Отображение типа java.lang.String в VARCHAR (либо Oracle VARCHAR2).

date, time, timestamp

Отображение типа java.util.Date и его подклассов в в SQL-типы DATE, TIME и TIMESTAMP (либо эквивалентные).

calendar, calendar_date

Отображение типа java.util.Calendar в SQL-типы TIMESTAMP и DATE (либо эквивалентные).

big_decimal

Отображение типа java.math.BigDecimal в NUMERIC (или Oracle NUMBER).

locale, timezone, currency

Отображение типа java.util.Locale, java.util.TimeZone и java.util.Currency в VARCHAR (или Oracle VARCHAR2). Экземпляры Locale и Currency отображаются в их ISO коды. Экземпляры TimeZone отображаются в их идентификаторы (ID).

class

Отображение типа java.lang.Class в VARCHAR (или Oracle VARCHAR2). Class отображается как его полное имя.

binary

Отображает массивы байтов в соответствующий бинарный SQL-тип.

text

Отображает длинные строки Java в SQL CLOB либо TEXT.

serializable

Отображает сериализуемые Java-типы в соответствующие бинарные SQL-типы. Вы так же можете обозначить Hibernate-типом serializable имя сериализуемого Java-класса либо интерфейса, который не является базовым типом и не реализует интерфейс PersistentEnum.

clob, blob

Отображение типа JDBC классов java.sql.Clob и java.sql.Blob. Эти типы могут быть неудобными для некоторых приложений, так как объекты типов blob и clob не могут использоваться вне транзакций. (К тому же, драйвера поддерживают эти типы не полностью и неодинаково.)

Уникальные идентификаторы сущностей и коллекций могут быть любого базового типа за исключением binary, blob и clob. (Составные идентификаторы так же допускаются, смотри ниже.)

Базовые типы-значения описываются константами объявленными в net.sf.hibernate.Hibernate. Например, Hibernate.STRING представляет тип string.

5.2.3. Персистентные перечисляемые типы (enum)

Перечисляемый тип является базовой идиомой Java когда класс имеет константное (небольшое) количество неизменяемых экземляров (прим. переводчика в Java 5 это введено на уровне языка, в более ранних версиях для этого применялся специальных паттерн). Вы можете создавать персистентные перечисляемые типы реализуя интерфейс net.sf.hibernate.PersistentEnum, и определяя операции toInt() и fromInt():

Package eg; import net.sf.hibernate.PersistentEnum; public class Color implements PersistentEnum { private final int code; private Color(int code) { this.code = code; } public static final Color TABBY = new Color(0); public static final Color GINGER = new Color(1); public static final Color BLACK = new Color(2); public int toInt() { return code; } public static Color fromInt(int code) { switch (code) { case 0: return TABBY; case 1: return GINGER; case 2: return BLACK; default: throw new RuntimeException("Unknown color code"); } } }

Имя Hibernate-типа - это просто имя перечисляемого класса, в данном случае eg.Color.

5.2.4. Пользовательские типы-значения

Для разработчиков относительно просто создать свои типы-значения. Например, вы можете захотеть сохранять свойства типа java.lang.BigInteger в колонки типа VARCHAR. Hibernate не предоставляет встроенного типа для этого. Но определение пользовательских типов не огранивается отображением свойств (либо элементов коллекций) в единичный столбец таблицы. Таким образом, например, вы можете иметь свойство getName()/setName() типа java.lang.String которое хранится в колонках FIRST_NAME, INITIAL, SURNAME.

Для реализации пользовательского типа, реализуйте один из интерфесов net.sf.hibernate.UserType либо net.sf.hibernate.CompositeUserType и объявите свойство, используя полное имя класса вашей реализации типа. Просмотрите net.sf.hibernate.test.DoubleStringType для уточнения доступных возможностей.

Примечание: используйте тэги для отображения свойства в несколько колонок.

Хотя богатство встроенных Hibernate-типов и поддержка компонентов подразумевает то, что нужда в использовании пользовательских типов возникает достаточно редко, все же считается хорошей практикой использование последних в качестве (не сущностных) классов для типов, часто используемых в вашем приложении. Например, класс MonetoryAmount хороший кандидат для CompositeUserType, хотя он может отображаться как компонент. Главная мотивация это абстракция. С пользователскими типами, ваш документ маппинга будет более усточивым к возможным изменениям в будущем в случае если вы измените представление денежного типа.

5.2.5. Отображение Any типа

Есть еще один тип для отображения свойств. Элемент отображения объявляет полиморфную ассоциацию для классов из нескольких таблиц. Этот тип отображения всегда требует более одной колонки. Первая колонка содержит тип ассоциированной сущности. Остальные колонки содержат идентификатор. Невозможно пределить внешний ключ для данного типа ассоциации, таким образом, это отображение обычно не используется для полиморфных ассоциаций. Вы должны использовать подобное отображение только в особых случаях (например, запись разнотипных данных, обращение к данным пользовательской сессии).

Атрибут meta-type позволяет приложению задать пользовательский тип, который отображает значения колонок базы данных в персистентные классы, свойства-идентификаторы которых имеют тип, определеный в id-type. Если мета-тип (meta-type) возвращает сущности java.lang.Class, то больше ничего не требуется. В остальных случаях, когда это базовый тип, такой как string или character вы должны определить соответствие значений классам.

..... .....

(1)

name: Имя свойства.

(2)

id-type: Тип идентификатора.

(3)

meta-type (необязательно - по умолчанию class): тип, который отображает java.lang.Class в одну колонку базы данных либо, в качестве альтернативы, тип, который разрешен для отображения дискриминатора.

(4)

cascade (необязательно - по умолчанию none): тип каскадной операции.

(5)

access (необязательно - по умолчанию property): Стратегия, которую должен использовать Hibernate для доступа к значению свойства.

Старое свойство object, которое занимает отдельное место в Hibernate 1.2, все еще поддерживается, но объявлено полу-устаревшим.

5.3. SQL-идентификаторы в кавычках

Вы можете принудить Hibernate заключать идентификаторы в кавычки в SQL выражениях. Hibernate будет следовать правилам заключения в кавычки согласно установленного диалекта SQL (обычно двойные кавычки, но скобки для SQL Server и обратные кавычки для MySQL).

...

5.4. Отдельные файлы отображения

Можно объявлять отображения subclass и joined-subclass в отдельных документах, прямо внутри элемента hibernate-mapping. Это позволяет расширять иерархию классов добавлением нового файла отображения. При таком подходе вы должны указать атрибут extends в отображении подкласса, содержащий имя предварительно замапленного суперкласса. Использование данной возможности делает важным порядок перечисления документов отображений.

Проблема

Вы выгрузили бухгалтерский отчет о затратах и хотите продемонстрировать его руководству. Для этого вам необходимо скомпоновать данные статей бухгалтерского учета - по статьям управленечского учета. Вы знаете, как соотносятся между собой статьи БУ и УУ, но каждый раз подготовка такого отчета вручную у вас занимает слишком много времени.

Решение

Будем рассматривать данный кейс как продолжение предыдущего. Представим себе, что вы создали в Excel такой справочник:

Рис.2.1. Справочник: мэппинг статей БУ и УУ


Слева - статья затрат (БУ), справа статья управленческого учета (УУ). Важно при этом, чтобы в первом колонке статья затрат встречалась только один раз, иначе механизм мэппинга будет работать не корректно.

(Кстати, английское слово mapping переводится как отображение или соответствие, поэтому справочник в данном случае - это некое общее правило того, как статьи БУ находят свое отображение в статья УУ).

Рис.2.2. Плоская таблица: отчет о затратах (из "Оборотов счета 20")


Обратим внимание, что в 7-м столбце появилась графа "Статья УУ". Напротив каждой статьи затрат мы проставили статью управленческого учета. Это можно сделать вручную, но гораздо удобнее воспользоваться таким инструментом:

Рис.2.3. Плоская таблица: отчет о затратах (из "Оборотов счета 20")


В нижней части формы указаны наименования страниц: "Главная" - это плоская таблица, в которой содержатся данные о затратах (рис.2.2), "спр" - это справочник (рис.2.1).

В верхней части формы указаны номер столбцов. Так, в данном случае, если данные в столбцах 1 справочника и 3 главной страницы совпадают, то данные из 2-го столбца справочника копируются в 7-й столбец главной страницы.

В этой форме также мнржество дополнительных опций. Например, можно включить галочки "Признак #2" и "Признак #3", и тогда перенесение данных из столбца 2 справочника в столбец 7 главной страницы будет возможно, если справочник и главная страница будуь совпадать сразу по двум или даже трем реквизитам.

В результате такой несложной операции с помощью сводной таблицы можно построить целый ряд различных аналитических отчетов, в которых одним из разрезов будет фигурироватл аналитика "Стаьья УУ". Например, такой:

Рис.2.4. Отчет по затратам арматурного цеха


Сравнение мэппинга с ВПР()

Многие пользователи хорошо знакомы и пользуются функцией ВПР() в такого рода ситуациях. Однако функция ВПР() хорошо работает только на небольших объемах данны, в то время как данная форма отлично справляется с обработкой таблтц Excel, даже если у вас в справочнике, скажем, 5000 строк, а на гоавной странице - 300 000 строк. Попробуйте проверить, и вы убедитесь, что на таких объемах ВПР() дает сбои. Кроме того, функция ВПР() создает значительную нагрузку на Excel, вынуждая его проводить большие объесы калькуляций. Форма мэппинга позволяет избежать этого недостатка: она запускается один раз, действует несколько секунд (при больших объемах минут) и после этого никаких дополнительных нагрузок на файл Excel уже не создается.

Дорогие друзья!

Сегодня мы рады сообщить вам о том, что наши разработчики реализовали возможность транспортировки данных по URL (mapping, мэппинг) за “пределы” целевой страницы.

С помощью данной функции можно передать все данные с полей формы на страницу, на которую переходит пользователь, отправляя вам лид. Благодаря этому, лид попадает не только во , но также может попасть сразу и в вашу базу, если на странице редиректа его “встретит” соответствующий скрипт.

Теперь нет необходимости в экспорте данных из системы обработки лидов! Вы можете отправлять и обрабатывать их сразу в собственной базе!

Так же, благодаря данной функции, становится возможным поздравить или поблагодарить пользователя, предоставившего свои контактные данные лично.

Как работает мэппинг (mapping)?

Суть мэппинга в том, что при отправке данных с полей формы, в ссылку, по которой происходит переадресация, добавляются их содержимое. URL приобретает вид: //my_site.com/?name=ИМЯ&email=АДРЕС_ЭЛЕКТРОННОЙ _ПОЧТЫ&phone=НОМЕР_ТЕЛЕФОНА&lead_id=225298.

Важно! В дополнение ко всем данным полей, всегда передается ID лида в параметре lead_id.

На странице же, на которую осуществоляется переход, данную информацию “принимает” специальный скрипт, который, в свою очередь, распределяет данные по соответствующим “ячейкам”.

Обращаем ваше внимание! Мэппинг работает только в том случае, если “Результат формы” - “Переход по URL”!

Как настроить “транспортировку” лида по URL (mapping) на моей целевой странице?

1. Войдите в .
2. Выберите страницу с формой лида, с которой вы собираетесь “транслировать” данные.

3. В редакторе сделайте двойной щелчок по форме.

4. В появившемся окне заполните графу “Mapping” соответствующими названиями полей на английском языке. Например,name - имя, phone - телефон и т. п.

5. Сохраните изменения.

6. В свойствах формы настройте редирект на нужную страницу - это может быть или страница вашего сайта, в которую встроен JavaScript, который и будет обрабатывать данные с полей, поступившие с URL.

Установите флажок в чекбоксе “Передать поля формы”.

7. Сохраните изменения в основном меню редактора.

Вот и все! :-)

Теперь данные с полей вашей формы будут передаваться на страницу, на которую вы переадресовываете пользователя. Вам не придется экспортировать лиды из CRM LPgenerator - они могут “транспортироваться” в вашу CRM прямо по URL. Возможности мэппинга (mapping) по транспортировке данных воистину безграничны.