Menu:

 
Популярные записи:

Похожие записи:

 

Отображение структуры реляционной СУБД в виде дерева при реализации

Использование древовидного отображения структуры реляционных СУБД при реализации пользовательского интерфейса дает ряд преимуществ, связанных с удобством навигации по элементам СУБД и администрированию. При этом способ построения такой структуры определяет время загрузки приложения и навигации по объектам в процессе работы. И если при реализации работы системы в режиме standalone выбор того или иного способа организации построения дерева не существенно сказывается на временных характеристиках, то при реализации распределенного приложения это сильно влияет на производительность всей системы в целом и является критичным. В этом случае, так же, по мимо выбора реализации способа построения древовидной структуры, на производительность системы влияет выбор стратегии кэширования и механизма транзакций. Целью данной работы является анализ способов построение древовидной структуры при разработке распределенной системы "Учет электротехнического оборудования ОАО "РОСТОВЭНЕРГО" и выбора оптимального из них с использованием технологий Java 2 [ ], СУБД HSQLDB [ ], MS SQL Server и Hibernate[ ] как средства отображения данных объектной модели на реляционную. Новизна работы заключается в том, что при реализации трехзвенной архитектуры распределенного приложения, слой, отвечающий за доступ к СУБД, реализован с помощью библиотеки Hibernate [ , ]. По способу загрузки элементов в древовидную структуру можно выделить статическое и динамическое построение дерева. Статическое построение дерева, как правило используется, когда заранее известна иерархическая структура, т.е. количество уровней. Отличительной особенностью такого построения является то, что в дальнейшей работе при попытке перейти на низший уровень не выполняется запросов к СУБД, т.е. дерево формируется сразу при загрузке программы и все дальнейшие манипуляции, связанные со вставкой или удалением нового объекта в дерево необходимо синхронизировать с СУБД. При динамическом построении, при загрузке формируется только самый высший уровень, а при попытке перейти к низшим уровням отслеживается соответствующее событие, например двойной «клик» на узле дерева, при этом формируется соответствующий запрос к СУБД, в результате которого осуществляется подгруздка необходимых данных в соответствующий узел. Так же следует заметить, что при статической реализации возможны следующие варианты: в коде отсутствует строгая реализация построения, а используется модуль, реализованный в виде интерфейса в котором описаны методы построения и заполнения узла дерева, а иерархия объектов дерева реализованная в виде XML файла конфигурации. К недостаткам первого способа можно отнести невозможность оперативного внесения каких либо корректив при изменении структуры, а также наложения каких либо ограничений на выборку бизнес объектов, например запрос с параметром и необходимость перекомпиляции исходных кодов в случае если такие изменения необходимо выполнить, что в конечном итоге сказывается на общем времени внесения изменений. К преимуществам данного способа следует отнести относительно небольшое время построения дерева, так как оно выполняется по четко запрограммированным алгоритмам для каждого конкретного объекта, а также размер дистрибутива, так как используются стандартные библиотеки. Второй способ статического построения является более гибким и связано это с тем, что все взаимосвязи объектов, а также ограничения, которые накладываются на выборку можно указать в тэгах XML документа, который будет проанализирован при загрузке дерева. Вместе с тем, у данного способа есть недостатки, которые прежде всего связаны с временем построения и загрузки приложения. Динамический способ формирования дерева имеет более простую реализацию, но является более ресурсоемким, так как в этом случае интенсивно посылаются запросы к СУБД при переходе на низшие уровни. Таким образом, каждый из описанных способов необходимо использовать с учетом конкретной ситуации, что может определять структура и характер приложения, используемые инструментальные средства. Безусловно, когда речь идет о сложных динамически изменяемых структурах, которые необходимо отображать с помощью пользовательского интерфейса, работающих в распределенной системе, использование первого способа является нецелесообразным. Поэтому представляется оптимальным вариантом использование комбинированного способа загрузки, когда начальный шаблон дерева формируется с помощью конфигурационного XML-файла, а объекты, иерархия которых заранее неизвестна динамически. При разработке алгоритмов построения дерева, был учтен характер сложных взаимосвязей объектов СУБД, распределенный характер приложения, и объемы хранимой информации. На первом этапе были определены элементы, которые будут загружаться в узлы дерева. Так как главное назначение дерева отображать структуру связанных сущностей СУБД, то основной вопрос связан с тем в каком виде загружать информацию о сущности, так как если загружать всю информацию о бизнес сущности в узел, т.е. бизнес объект со всеми его атрибутами, то это может привести к неоправданному расходу ресурсов, которые связаны как с выделением памяти под структуру, так и с нагрузкой на СУБД. Поэтому был создан специальный объект для отображения сущности в дереве (NodeTreeObj), рисунок 1, который в хранит только идентификатор сущности, ее класс и название, а для отображения имени объекта в узле дерева, в его классе был переопределен метод toString(). В связи с тем, что бизнес объекты имеют сложные взаимосвязи, и стержневые сущности могут иметь множество характеристических, т.е. одни объект может “агрегировать” множество объектов разных классов, при чем в зависимости от ситуации детализация объекта может быть разной, было принято решение создать специальный объект группировки (GroupNode), рисунок 2, с помощью которого можно было бы решать поставленную задачу. Взаимосвязь между данными объектами в дереве следующая, объект группировки может содержать множество объектов NodeTreeObj. Объект NodeTreeObj может содержать в себе как объекты GroupNode так и объекты NodeTreeObj. Логику построения дерева при загрузке программы можно описать следующим образом. В начале должен анализироваться xml документ, в результате чего в памяти создается коллекция объектов группировки в виде списка - ArrayList. Как видно из рис.2 класс объекта группировки GroupNode, является полиморфическим, т.е. в зависимости от значений тэгов xml документа может иметь две различные реализации. В данном случае анализируется тэг – признак "наличие запроса с параметром к СУБД". Если данный тэг не установлен, то формируется Hibernate – запрос на выборку всех экземпляров сущности, Листинг 1. Листинг 1. Фрагмент кода, класса SAX - анализатора. /** * Метод обработки начала элемента */ public void startElement(String uri, String Sname, String qname, Attributes attr)throws SAXException { // Обработка события на начало тэга if(qname.equals("groupnode")) { try { baseObject = Class.forName(attr.getValue("baseobject")); parNameNode = attr.getValue("parnamenode"); parent = Class.forName(attr.getValue("parent")); visible = new Boolean(attr.getValue("visible")).booleanValue(); enabled = new Boolean(attr.getValue("enabled")).booleanValue(); parameter = new Boolean(attr.getValue("parameter")).booleanValue(); nameNode = attr.getValue("namenode") ; // Создаем экземпляр классаGroupNode... //проверяем есть ли запрос с параметром if(parameter) { nameField = attr.getValue("nameField"); typeField = attr.getValue("typeField"); valueField = attr.getValue("valueField"); groupNode = new GroupNode(baseObject,nameNode,parNameNode, parent, visible,enabled,parameter,nameField,typeField,valueField); } else groupNode = new GroupNode(baseObject,nameNode, parNameNode, parent,visible,enabled,parameter); listGroupNode.add(groupNode); } catch (ClassNotFoundException ex) { ex.printStackTrace(); } .......... .......... Листинг 2. Фрагмент конфигурационного xml - файла, для построения дерева <config> <!-- Описание элементов и атрибутов: Элемент: groupnode – элемент объект - группировки Атрибуты: baseobject- основная бизнес сущность, объекты которой выбираются в групповую ноду из СУБД nameNod - наименование узла для отображения в дереве parnamenode - имя родительского узла группировки parent - имя родительского класса бизнес сущности (Варианты значений: 1. имя имеющейса бизнесс сущности с точным указанием пакета, например ru.rosten.glip.entities.OrgUnit 2. если узел корневой то класс "javax.swing.tree.TreeNode") visible - Признак видимости групипровки enabled - признак доступности parameter - признак наличия параметров запроса при выборке бизнес сущности в групповой узел (flase - нет параметров true – есть) namefield - имя поля type – тип поля (long или String) value - значение параметра --> <!--Корневая нода для организаций --> <groupnode baseobject="ru.rosten.glip.entities.OrgUnit" namenode="Сетевые компании" parnamenode="Root" parent="javax.swing.tree.TreeNode" visible="true" enabled="true" parameter="true" nameField="orgUnitLevel" typeField="long" valueField="1" /> <!--Нода для организаций второго уровня --> <groupnode baseobject="ru.rosten.glip.entities.OrgUnit" namenode="ПЭС" parnamenode="Сетевые компании" parent="ru.rosten.glip.entities.OrgUnit" visible="true" enabled="true" parameter="false" nameField="orgUnitLevel" typeField="long" valueField="2" /> После того, как в памяти созданы все объекты группировки, начинается процесс формирования дерева и вывода его на экран. Далее уже все основные манипуляции осуществляются через коллекцию созданных объектов в памяти. В начале выбираются корневые объекты, от которых уже выполняются дальнейшие построения, Листинг 3. Листинг 3. Фрагмент кода создания корневых элементов. listGroupNode = treeHandler.getListGroupNode(); for (Object elem : listGroupNode) { // проверяем загруженный список на наличие корневых нод if(javax.swing.tree.TreeNode.class.equals(((GroupNode) elem).getParentObj())) { root.add((GroupNode) elem); // проверяем есть ли запросы с параметром if(((GroupNode) elem).isParameter()){ // если есть проверяем какого типа параметр if(((GroupNode) elem).getTypeField().equals("String")) this.createNode((GroupNode) elem,queryDB.getParamColNto( ((GroupNode) elem).getBaseObject(), ((GroupNode) elem).getNameField(), ((GroupNode) elem).getValueField(), ((GroupNode) elem).getValueField() )); if(((GroupNode) elem).getTypeField().equals("long")) this.createNode((GroupNode)

Похожие статьи:

 

Сайт управляется системой uCoz