diff --git a/doc/content/manual/ru/chapter_framework.xml b/doc/content/manual/ru/chapter_framework.xml index 17ee547d81..9ed835ac8a 100644 --- a/doc/content/manual/ru/chapter_framework.xml +++ b/doc/content/manual/ru/chapter_framework.xml @@ -8610,36 +8610,144 @@ protected boolean postCommit(boolean committed, boolean close) {
Источники данных - Предназначены для реализации связанных с данными (data-aware) компонентов. - Существуют следующие интерфейсы источников данных: - - - Datasource − предназначен для работы с одним экземпляром сущности. - - - RuntimePropsDatasource − предназначен для работы с динамическими атрибутами сущностей. - - - - - CollectionDatasource − предназначен для работы с коллекцией сущностей - - - HierarchicalDatasource − предназначен для работы с компонентами - Tree - , - TreeTable - . - - - GroupDatasource − предназначен для работы с компонентом - GroupTable - . - - - - - Как правило, источники данных объявляются декларативно в секции dsContext дескриптора экрана. +
+ Общие сведения + Источники данных обеспечивают работу связанных с данными (data-aware) компонентов. + Визуальные компоненты сами не обращаются к Middleware, а получают экземпляры сущностей из связанных источников данных. При этом один источник данных может обслуживать несколько визуальных компонентов, если им нужен один и тот же экземпляр или набор экземпляров. + Источники данных также отслеживают изменения содержащихся в них сущностей, и могут отправлять измененные экземпляры обратно на Middleware для сохранения в базе данных. + Рассмотрим основные интерфейсы источников. +
+ Интерфейсы источников данных + + + + + +
+ + + Datasource − простейший источник данных, предназначенный для работы с одним экземпляром сущности. Экземпляр устанавливается методом setItem() и доступен через getItem(). + Стандартной реализацией такого источника является класс DatasourceImpl, который используется, например, как главный источник данных в экранах редактирования сущностей. + + + CollectionDatasource − источник данных, предназначенный для работы с коллекцией экземпляров сущности. Коллекция загружается при вызове метода refresh(), ключи экземпляров доступны через метод getItemIds(). Метод setItem() устанавливает, а getItem() возвращает "текущий" экземпляр коллекции, т.е. например соответствующий выбранной в данный момент строке таблицы. + Способ загрузки коллекции сущностей определяется реализацией. Наиболее типичный - загрузка с Middleware через + DataService + , при этом для формирования JPQL запроса используются методы setQuery(), setQueryFilter(). + Стандартной реализацией такого источника является класс CollectionDatasourceImpl, который используется в экранах, отображающих списки сущностей. + + + GroupDatasource − подвид CollectionDatasource, предназначенный для работы с компонентом + GroupTable + . + Стандартной реализацией является класс GroupDatasourceImpl. + + + HierarchicalDatasource − подвид CollectionDatasource, предназначенный для работы с компонентами + Tree + и + TreeTable + . + Стандартной реализацией является класс HierarchicalDatasourceImpl. + + + + + NestedDatasource - источник данных, предназначенный для работы с экземплярами, загруженными в атрибуте другой сущности. При этом источник, содержащий сущность-хозяина, доступен методом getMaster(), а мета-свойство, соответствующее атрибуту хозяина, содержащему экземпляры данного источника, доступно через метод getProperty(). + Например, в источнике dsOrder установлен экземпляр сущности Order, содержащий ссылку на экземпляр Customer. Тогда для связи экземпляра Customer с визуальными компонентами достаточно создать NestedDatasource, у которого хозяином является dsOrder, а мета-свойство указывает на атрибут Order.customer. + + + PropertyDatasource - подвид NestedDatasource, предназначенный для работы с одним экземпляром или коллекцией связанных сущностей, не являющихся встроенными (embedded). + Стандартные реализации: для работы с одним экземпляром - PropertyDatasourceImpl, для работы с коллекцией - CollectionPropertyDatasourceImpl, GroupPropertyDatasourceImpl, HierarchicalPropertyDatasourceImpl. Последние реализуют также интерфейс CollectionDatasource, однако некоторые его нерелевантные методы, связанные с загрузкой, например setQuery(), выбрасывают UnsupportedOperationException. + + + EmbeddedDatasource - подвид NestedDatasource, содержащий экземпляр встроенной сущности. + Стандартной реализацией является класс EmbeddedDatasourceImpl. + + + + + RuntimePropsDatasource − специфический источник, предназначенный для работы с динамическими атрибутами сущностей. + + + Как правило, источники данных объявляются декларативно в секции dsContext дескриптора экрана. +
+
+ Создание источников данных +
+ Декларативное создание + Как правило источники данных объявляются декларативно в элементе dsContext дескриптора экрана. В зависимости от взаимного расположения элементов объявлений создаются источники двух разновидностей: + + если элемент расположен непосредственно в dsContext, создается обычный Datasource или CollectionDatasource, который содержит независимо загруженную сущность или коллекцию; + + + если элемент расположен внутри элемента другого источника, создается NestedDatasource, при этом внешний источник становится его хозяином. + + + Все созданные декларативно источники данных регистрируются в объекте DsContext экрана. DsContext решает следующие задачи: + + Позволяет организовать зависимости между источниками данных, когда при навигации по одному источнику (т.е. при изменении "текущего" экземпляра методом setItem()) обновляется связанный источник. Такие зависимости дают возможность в экранах легко организовывать master-detail связи между компонентами. + + + Позволяет собрать все измененные экземпляры сущностей и отправить их на Middleware в одном вызове DataService.commit(), т.е. сохранить в базе данных в одной транзакции. + + + Класс реализации источника выбирается неявно на основе имени элемента XML и, как было сказано выше, взаимного расположения элементов. Однако если необходимо применить нестандартный источник данных, его класс может быть явно указан в атрибуте datasourceClass. +
+
+ Прораммное создание + При необходимости создать источник данных в Java коде рекомендуется воспользоваться специальным классом DsBuilder. + Экземпляр DsBuilder параметризуется цепочкой вызовов его методов в стиле текучего (fluent) интерфейса. Если установлены параметры master и property, то в результате будет создан NestedDatasource, в противном случае - Datasource или CollectionDatasource. + Пример:CollectionDatasource ds = new DsBuilder(getDsContext()) + .setJavaClass(Order.class) + .setViewName(View.LOCAL) + .setId("ordersDs") + .buildCollectionDatasource(); +
+
+
+ Собственные классы реализации + Как правило, нестандартная реализация источника данных требуется для изменения процесса загрузки коллекции сущностей. При создании класса такого источника рекомендуется унаследовать его от CollectionDatasourceImpl, либо от GroupDatasourceImpl или HierarchicalDatasourceImpl, и переопределить метод loadData(). + Пример:public class MyDatasource extends CollectionDatasourceImpl<SomeEntity, UUID> { + + private SomeService someService = AppBeans.get(SomeService.NAME); + + @Override + protected void loadData(Map<String, Object> params) { + detachListener(data.values()); + data.clear(); + + for (SomeEntity entity : someService.getEntities()) { + data.put(entity.getId(), entity); + attachListener(entity); + } + } +} + Здесь data - поле базового класса, хранящее коллекцию загруженных экземпляров. Методы базового класса detachListener() и attachListener() управляют назначением на загруженные сущности слушателя, который оповещает источник данных об изменениях в полях экземпляров. + Для создания нестандартного источника данных декларативным способом необходимо указать класс в атрибуте datasourceClass элемента XML. При программном содании через DsBuilder класс источника указывается вызовом setDsClass(). +
+
+ Запросы в CollectionDatasourceImpl + Класс CollectionDatasourceImpl и его наследники GroupDatasourceImpl, HierarchicalDatasourceImpl являются стандартной реализацией источников данных, работающих с коллекциями независимых экземпляров сущностей. Эти источники загружают данные через DataService, отправляя на Middleware запрос на языке JPQL. Далее рассмтриваются особенности формирования таких запросов. +
+ Возвращаемые значения + Запрос должен возвращать сущности того типа, который указан при создании источника данных. Тип сущности при декларативном создании указывается в атрибуте class элемента XML, при создании через DsBuilder - в методе setJavaClass() или setMetaClass(). + Кроме того, тип объекта в предложении from запроса должен соответствовать типу источника. Это необходимо для проведения автоматических транформаций запроса при наложении ограничений безопасности и др. + Например, запрос источника данных типа Customer может выглядеть следующим образом:select c from sales$Customer c + Примеры недопустимых для источника типа Customer запросов:select c.id, c.name from sales$Customer c /* неверно - возвращает отдельные поля, а не весь объект Customer */ + +select o.customer from sales$Order o /* неверно - тип from (Order) отличается от типа результата (Customer) */ +
+
+ Параметры запроса + JPQL запрос в источнике данных может содержать параметры нескольких видов. Вид параметра определяется по префиксу имени параметра. Префиксом является часть имени до знака "$". + + Префикс ds. + Значением параметра являются данные другого источника данных, имя которого указано после символа "$". + + +
+
Фоновые задачи