Устройство класса#
На странице описаны окружение и кодогенерация класса, доступные прикладные сервисы, типы данных и атрибутов, глобальные идентификаторы, супертипы и разметка.
Класс определяет правила хранения и обработки данных в таблице базы данных.
Общие сведения о классах#
Класс сущности (далее — класс) определяет хранилище совокупности объектов (строк), которые имеют одинаковые характеристики, подчиняются общим настройкам и операциям и функционируют в рамках единой логики.
Класс содержит набор атрибутов. Атрибут может быть:
простым значением — используется для ввода и хранения значения определённого типа данных;
ссылочным — используется для выбора значения из справочника или другого множества;
переменной ссылкой — используется для ссылки на любую таблицу в системе;
ссылкой на класс — таблица классов является служебной таблицей метаданных, в которой хранится весь перечень классов решения.
Класс должен иметь уникальные системное имя и наименование.
Правила именования класса:
Системное имя задаётся на латинице.
Имя задаётся в формате
{Module}_{Name}, где:Module— имя модуля;Name— имя класса в единственном числе и именительном падеже.
Пример: Lbr_Book.
Типы данных (attribute-type)#
Системное имя |
Наименование |
Хранение (PostgreSQL) |
Особенности |
|---|---|---|---|
|
Строка |
|
Рекомендуемый тип для строк. Ограничение длины — обычно до 4000 символов |
|
Текст |
|
Тип строк. Запрещён к использованию, так как является неограниченным типом данных |
|
Большой текст |
|
Используется для хранения больших текстов |
|
Число |
|
Поддерживает целые и дробные значения ( |
|
Целое число |
|
Используется для |
|
Дата |
|
Поддерживает дату и время |
|
Бинарные данные |
|
Хранит файл без метаданных |
|
JSON |
|
Данные без фиксированной схемы |
Типы атрибутов (type)#
Тип |
Описание |
Примечание |
|---|---|---|
|
Значимый атрибут |
Используется для хранения простых значений ( |
|
Ссылка на объект |
Хранит |
|
Глобальная ссылка |
Хранит GID в виде строки. Используется для интеграций |
|
Переменная ссылка |
Хранит GID. Позволяет ссылаться на любой класс |
|
Ссылка на класс |
Применяется для ссылок на класс |
|
Ссылка на группу классов |
Позволяет ограничить ссылку набором классов |
|
Ссылка на состояние |
Используется для ссылок на состояние |
|
Ссылка на группу |
Предназначен для ссылок на группы ( |
|
Автонумерация |
Значение генерируется системой |
|
Вычисляемый атрибут |
Не хранится в базе данных. Вычисляемые значения реализуются на уровне выборок без объявления атрибута в ODM |
Примеры использования#
1. Простой атрибут строкового типа
<attr name="sCaption"
attribute-type="Varchar"
type="basic"
caption="Наименование"/>
2. Ссылка на объект
<attr name="idState"
attribute-type="Long"
caption="Состояние"
type="refObject"
ref.class="Btk_ClassState"/>
3. Ссылка на класс (refClassByRoot)
<attr name="idContactClass"
attribute-type="Long"
caption="Класс контактной информации"
type="refClassByRoot"
ref.class="Btk_Class"/>
4. Ссылка на группу классов (refClassByUnion)
<attr name="idWorkDirClass"
attribute-type="Long"
caption="Область применения"
type="refClassByUnion"
ref.class="Bs_WorkDirClassArray"/>
5. Ссылка на группу (refGroup)
<attr name="idRefGroup"
attribute-type="Long"
caption="Группа"
type="refGroup"
ref.class="Btk_Group"/>
Приведение типов атрибутов#
При работе с динамическими атрибутами значения часто поступают в строковом виде (sDefaultValue). Для корректной обработки требуется явное приведение типов.
Пример:
// sDefaultValue — строковое значение
// если атрибут ссылочный
if (attr.get(_.sType) === AttrTypes.RefObject.toString)
sDefaultValue.nl
// если атрибут переменной ссылочности
else if (attr.get(_.sType) === AttrTypes.RefAnyObject.toString)
sDefaultValue.ng
// если атрибут дата
else if (attr.get(_.sAttrType) === AttributeTypes.Date.toString.ns) {
NDate.parse(sDefaultValue.get)
}
// если атрибут числового типа
else if (attr.get(_.sAttrType) === AttributeTypes.Number.toString.ns)
sDefaultValue.nr
// если атрибут целочисленного типа
else if (attr.get(_.sAttrType) === AttributeTypes.Long.toString.ns)
sDefaultValue.nl
// по умолчанию — строка
else {
sDefaultValue
}
JSON-контейнер#
JSON-контейнер — это расширение объекта класса NoSQL-нотацией в реляционной СУБД. Контейнер не имеет жёсткой, заранее определённой схемы и основан на множестве пар «ключ — значение». Это позволяет использовать его как динамическое расширение объекта. Для добавления новых данных в контейнер не требуются перекомпиляция кода или изменение структуры СУБД.
Кодогенерация и прикладные сервисы#
Класс позволяет существенно ускорить разработку бизнес-логики, ориентированной на работу с данными. Разработчику достаточно объявить перечень атрибутов класса, чтобы за счет кодогенерации получить набор готовых сервисов.
При кодогенерации создаются следующие элементы:
Доменная автономная бизнес-логика (
Dpi) — содержит код автономной бизнес-логики.Каркас прикладной автономной логики (
Api) — Scala-класс с окончаниемApi, в котором задаётся автономная бизнес-логика для работы с классом. Наследуется отDpi.Доменная интерактивная бизнес-логика (
Dvi).Каркас прикладной интерактивной логики (
Avi) — Scala-класс с окончаниемAvi, в котором задаётся интерактивная бизнес-логика. Наследуется отDvi.Доменная разметка выборки (
dvm.xml) — содержит сгенерированную по умолчанию разметку выборки.Каркас прикладной декларации пользовательского интерфейса (
Avm) — XML-файл с расширениемavm.xml, в котором задаётся разметка выборки.Интеграция с ORM:
POJO-объект для хранения данных в кеше;
Aro— объект интеграции POJO во фреймворк.
Примечание
При кодогенерации обычно создаются элементы двух типов:
D— Domain. Доменный элемент всегда перезаписывается при кодогенерации и содержит бизнес-логику для подключения сервисов.A— Application. Прикладной элемент не изменяется при кодогенерации и служит для хранения бизнес-логики, написанной программистом вручную. Прикладной элемент наследуется от доменного.
Доступные прикладные сервисы:
Аудит — фиксирует события, возникающие при работе пользователей в системе.
Администрирование — позволяет управлять доступом к автономной и интерактивной бизнес-логике за счёт выдачи прав на привилегии.
Универсальная фильтрация — позволяет пользователю строить комплексную фильтрацию списка классов на уровне базы данных. В универсальном фильтре можно использовать поля самого класса и его коллекций, а также поля классов, на которые есть ссылки.
Автонумерация — выдаёт номера объектам класса и позволяет переопределять алгоритм выдачи номеров на проекте.
Копирование объектов — обеспечивает кодогерацию бизнес-логики для копирования объектов.
Группировка — используется для систематизации хранения объектов и удобства их восприятия. Группировка также позволяет массово управлять характеристиками и настройками объектов класса.
Сервис прикреплённых файлов — позволяет прикреплять к объектам класса произвольные файлы.
Поиск по шаблону — позволяет искать объекты класса по частичному или полному совпадению введённого текста со значениями полей, заголовком или мнемокодом объекта.
Объектные характеристики — позволяют добавлять к классу на проекте произвольные поля.
Генерация штрихкодов объекта — генерирует штрихкоды для объектов класса при их создании.
Подписи объектов для печати — позволяют формировать в печатной форме список лиц с местом для подписи.
Полнотекстовый поиск — позволяет классу выполнять быстрый поиск по значениям его атрибутов.
Схема окружения#
Окружение класса создаётся в момент кодогенерации:

Глобальный идентификатор GID#
GID является уникальным идентификатором в рамках системы.
Генерация GID необходима для решения следующих задач:
Уникальная идентификация — обеспечивает уникальную идентификацию каждого объекта в рамках системы независимо от его типа.
Переменная ссылочность — обеспечивает возможность хранить ссылку на объект любого класса в одном атрибуте.
Системная интеграция — GID является частью системного миксина
btk_object. Подробнее см. в разделе «Системные миксины».
Переменная ссылка на GID является альтернативой системе переменной ссылочности, состоящей из двух атрибутов: ссылки на класс и переменной ссылки на объект. Для организации переменной ссылки через GID используется один атрибут.
Формат ссылки GID#
Глобальный идентификатор имеет формат:
gid :== idClass \ id
где:
idClass— идентификатор класса, ссылающийся на объект в таблицеbtk_class;id— уникальный идентификатор конкретного объекта внутри класса. Идентификатор не является уникальным в системе, так как генерируется для каждого класса из отдельной последовательности (sequence).
Внешние ключи и их роль в GID#
Внешний ключ — это столбец или набор столбцов одной таблицы, который ссылается на первичный ключ другой таблицы.
Внешний ключ гарантирует, что ссылка, хранящаяся через GID, указывает на существующую запись, и предотвращает появление «битых» связей.
Пример:
<attr name="gidSrc" attribute-type="Varchar" caption="Источник" order="60" type="refAnyObject" isVisible="false"/>
<attr name="idDoc" attribute-type="Long" type="refObject" ref.class="Wf_Doc"/>
<attr name="idAction" attribute-type="Long" type="refObject" ref.class="Pro_Action"/>
В этом примере параметр type="refObject" вместе с ref.class="Wf_Doc" означает, что атрибут является ссылкой на объект указанного класса. Атрибут хранит идентификатор связанной записи, обеспечивая логическую связь между объектами.
Создание внешнего ключа
Внешний ключ создаётся автоматически при указании ссылочности на класс.
Чтобы создать внешний ключ вручную:
Создайте расчётную колонку, выделяющую идентификатор объекта из GID:
ALTER TABLE event_log ADD COLUMN id_doc bigint GENERATED ALWAYS AS (split_part(gid_src, '\\', 2)::bigint) STORED;
Значение
id_docавтоматически вычисляется изgid_src.Добавьте внешний ключ:
ALTER TABLE event_log ADD CONSTRAINT fk_event_log_doc FOREIGN KEY (id_doc) REFERENCES wf_doc(id);
Примечание
Таких колонок может быть несколько — по одной на каждую логическую связь.
Выявление существующих нарушений
Для анализа существующих нарушений ссылочности используются разные инструменты в зависимости от типа ссылки:
Для обычных ссылок с внешними ключами используется «Сервис проверки целостности ссылок».
Для GID-ссылок используется «Отчёт по нарушенной переменной ссылочности». Отчёт показывает некорректные GID-ссылки, которые указывают на несуществующий класс или объект класса либо не соответствуют формату GID.
Реализация переменной ссылочности через GID#
Переменная ссылочность
GID упрощает реализацию переменной ссылочности, так как содержит всю необходимую информацию — класс и идентификатор. Для реализации переменной ссылочности создаётся атрибут, способный хранить GID:
<attr name="gidSrcXxxxxx"
attribute-type="String"
type="refAnyObject"/>
Ссылочность на миксин
Ссылка на миксин — это переменная ссылочность с дополнительным полем ref.class, указывающим класс миксина. Подробнее см. в разделе «Ссылочность на миксин».
Генерация GID#
Классы с автоматической генерацией GID
GID генерируется автоматически для:
классов с подтипом сущности
referenceилиdocument;классов с тегом
attachTypeв ODM-файле, обеспечивающим поддержку прикреплённых файлов у значений:simple— обычная;versioned— версионная;
классов с подключёнными
vCollections— коллекциями с переменной ссылочностью.
В остальных случаях GID не генерируется автоматически.
Ручная генерация GID
Чтобы сгенерировать GID вручную:
Укажите атрибут GID в классе:
<attr name="gid" attribute-type="Varchar" isVisible="false"/>
Чтобы заполнить пустые значения GID, выполните операцию «Заполнить пустые gid и обновить системные миксины для класса».
Путь: Дополнительно → Заполнить пустые gid и обновить системные миксины для класса.
Примечание
Операция также обеспечивает попадание в миксин btk_object.
Супертипы классов#
Для проектирования доступно несколько разновидностей класса, с помощью которых можно реализовать модель с необходимой бизнес-логикой. Такие разновидности называются супертипами.
Супертип определяет базовое назначение класса и влияет на работу системы с объектами этого класса.
Для класса супертип задаёт:
стандартное поведение объекта;
набор базовых методов и сервисной обвязки;
особенности хранения и обработки данных;
допустимые сценарии использования класса в прикладной модели;
ограничения на самостоятельное существование объектов, если они предусмотрены выбранным супертипом.
Супертип должен быть указан для каждого класса. Если супертип не задан явно, класс считается обычным справочником и обрабатывается как класс с супертипом reference.
Основные супертипы:
reference— справочник. Справочник — это прикладной объект для хранения данных, имеющих одинаковую структуру и списочный характер. Примеры: справочник физических лиц, места хранения, справочник ТМЦ.document— документ. Документ — это прикладной объект, который хранит данные о событиях или операциях на предприятии. Примеры: заявка на отгрузку, приходная накладная, акт сверки. Документ обычно имеет атрибут состояния, который отражает его жизненный цикл.collection— коллекция. Объекты класса-коллекции не могут существовать самостоятельно и создаются только для объектов других классов. Коллекции применяются как табличные части документов или логические развязки между классами. Добавление коллекций в бизнес-объект позволяет массово загружать данные в объектный кеш, что минимизирует нагрузку на базу данных. Элементы коллекции также можно обходить по родителю без транзакционного индекса, что уменьшает нагрузку на процессор.vcollection— переменная коллекция. Переменная коллекция расширяет возможности обычных коллекций и может ссылаться на родителя переменной ссылкой. Это требуется, когда для нескольких классов используется одинаковая коллекция.journal— журнал. Журнал — это особый тип класса, приспособленный для хранения большого количества записей. Такие классы имеют ограниченную функциональную обвязку ядровыми методами фреймворка, что позволяет увеличить быстродействие при работе с журналом. Примеры: записи по потребности ТМЦ на заказ в разрезе документов, журнал трудоёмкости в разрезе операций.trait— трейт. Абстрактный класс-предок, не имеющий собственной структуры хранения. Такой класс содержит общую логику нескольких классов-потомков и является частью механизма повторного использования кода.mixin— миксин (класс-примесь). Миксин — это особый вид класса, который служит для хранения данных из разных классов. Миксины используются для построения общих списочных форм различных диалогов подбора в пользовательских интерфейсах, а также для обработки данных в прикладной бизнес-логике. Миксин позволяет объединить несколько таблиц, что даёт возможность использовать внешние ключи и индексы для этого объединения.simpleMixin— простой миксин. Простой миксин — это класс-примесь, не являющийся коллекцией по отношению к реализующему его классу. Используется для подключения дополнительного набора атрибутов или логики к различным классам без создания отдельной коллекционной структуры. Позволяет повторно использовать общие поля и поведение в нескольких объектах.sharedReference— разделяемый справочник. Разделяемый справочник оптимизирован для совместного использования и интенсивного чтения данных. Использует механизм общего кеширования и предназначен для хранения редко изменяемых нормативно-справочных данных, доступных многим пользователям и процессам. Класс не может иметь миксинов. Механизм позволяет снизить нагрузку на базу данных при частом обращении.classArray— массив классов. Служебный супертип для хранения или обработки набора ссылок на объекты различных классов в рамках единой структуры.setting— настройка. Класс для хранения конфигурационных данных и параметров настройки системы или её модулей. Используется для управления поведением приложения без изменения кода.simpleExtension— простое расширение. Класс с дополнительными атрибутами, расширяющий базовый класс без изменения его основной структуры. Применяется, когда к существующему классу требуется добавить специфичные поля, не затрагивая его исходную схему. Подробнее см. в разделе «Классы-расширения. Simple Extensions».
Пример разметки класса#
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<class xmlns="http://www.global-system.ru/xsd/global3-class-1.0" name="Bs_GdsCostDeviationType"
caption="Виды отклонений в стоимости ТМЦ"
cardEditor.representation="Card" listEditor.representation="List"
viewOptions.openCardType="mdi" supertype="reference">
<attributes>
<attr name="id" attribute-type="Long" caption="Идентификатор" order="-1" type="basic" isVisible="false"/>
<attr name="idClass" attribute-type="Long" caption="idClass" order="-2" type="basic" isVisible="false"/>
<attr name="gid" attribute-type="Varchar" isVisible="false"/>
<attr name="sCode" attribute-type="Varchar" caption="Код" order="10" isMnemoCode="true" type="basic"
isRequired="true" isVisible="true"/>
<attr name="sCaption" attribute-type="Varchar" caption="Наименование" order="20" isHeadLine="true" type="basic"
isRequired="true" isVisible="true"/>
<attr name="sDescription" attribute-type="Varchar" caption="Описание" order="30" type="basic" editorType="memo"
isVisible="true">
<descriptionColumn/>
</attr>
</attributes>
</class>