Использование функций интегрирования IBM Lotus Domino и IBM DB2 для усовершенствования приложений Lotus Domino

Научитесь использовать IBM® DB2® для хранения данных IBM Lotus® Domino®. В данной статье на примере описаны четыре возможных сценария применения функций интеграции Lotus Domino и DB2 в простых приложениях Lotus Domino.

Карен Брент, менеджер по предварительным версиям Lotus, BetaWorks, IBM

Карен Брент (Karen Brent) 9 лет проработала в компании IBM в Великобритании, сначала в сервисном подразделении Lotus, где она помогала заказчикам в разработке, развертывании и управлении архитектурой Lotus Notes и Domino. В настоящий момент она является руководителем проекта Lotus Early Program Manager в команде BetaWorks и оказывает помощь клиентам, пользующимся beta-версией в развертывании бета-версий и ранних выпусков программного обеспечения, обеспечивает связь между командами разработчиков с потребителями и помогает сотрудникам служб продажи и сервиса в мероприятиях по техническому обучению заказчиков.



13.08.2009

Функции интеграции IBM Lotus Domino и IBM DB2 были изначально выпущены в пробной форме в Lotus Notes® и Domino 7, а теперь они полностью поддерживаются в Lotus Notes и Domino 8.

Эти функции позволяют легко создавать приложения, которые динамически интегрируют внутренние данные DB2 (или данные, находящиеся в хранилищах, доступных из DB2) с данными Lotus Domino. Кроме того, эти интегрированные данные оказываются доступны в представлениях Lotus Domino и/или DB2, в зависимости от требований, предъявляемых к конкретному приложению. Это открывает много интересных возможностей для организаций, уже использующих DB2 или иные реляционные базы данных, которые могут быть вызваны из DB2, например, SAP или PeopleSoft. Web-доступ к этим интегрированным данным можно организовать либо через HTTP-доступ к приложениям Lotus Domino, либо через JDBC-доступ к представлениям DB2.

Кроме того, Lotus Notes и Domino 8 включают лицензию на использование DB2 в качестве информационного массива для данных Lotus Domino. Эта лицензия позволяет без дополнительных затрат на программное обеспечение пользоваться потенциально полезными возможностями для приложений, в которых данные хранятся исключительно в информационном хранилище Lotus Domino. Данный документ фокусируется на потенциальных преимуществах функций интеграции Lotus Domino и DB2 для простых приложений Lotus Domino, которым не требуется интеграция с существующими внешними данными DB2.

Важно понимать, что функции интегрирования Lotus Domino и DB2 не могут подходить для любых приложений Lotus Domino. Опыт подтверждает, что наилучшими кандидатами являются приложения Lotus Domino, имеющие следующие характеристики:

  • не требуется полная репликация приложения на клиент Lotus Notes.
  • не требуется (или требуется в ограниченных масштабах) отображать полную базу данных в представлении
  • имеется множество схожих представлений, категоризирующих одну и ту же информацию разными способами
  • пользователи при выполнении 80-90 процентов работы обращаются к небольшому количеству документов
  • полезно иметь возможность объединять данные из различных баз Lotus Notes
  • также полезно использовать средства SQL для генерации отчетов.

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

В данной статье мы мы на примере приложения разбираем четыре возможных сценария использования для функций интеграции Lotus Domino и DB2 в простых приложениях Lotus Domino и объясняем, когда и как они могут положительно воздействовать на приложение за счет улучшения производительности или повышения функциональности. При прочтении данной статьи могут пригодиться некоторые знания о проектировании приложений Lotus Notes, но мы излагаем разработку и кодирование примера приложения максимально просто, чтобы можно было легко понять основные принципы даже при отсутствии большого опыта разработки приложений.

Обратите внимание, что описанные в следующих сценариях функции доступны только если приложение находится под управлением сервера Lotus Domino, поддерживающего DB2. При репликации приложения на сервер Lotus Domino, не поддерживающий DB2, или на клиент Lotus Notes описанные выше функции будут недоступны.

Первый сценарий: реализация независимости данных в приложении Lotus Notes

Lotus Notes и Domino не являются платформой для приложений реляционной базы данных. Однако иногда бывает полезно добавить некоторые возможности реляционной базы данных в приложение Lotus Notes для достижения большей гибкости при сортировке и категоризации данных внутри приложения.

Например, предположим, что имеется приложение, в котором регистрируются сведения о мероприятиях, которые проводит наша компания. Мы хотим сохранять информацию о мероприятии (наименование, регион проведения, дату, стоимость), представленные темы и участников, посетивших данное мероприятие. Каждое мероприятие охватывает несколько тем и имеет несколько участников. Тема может находиться в повестке дня нескольких мероприятий, участник также может посетить несколько мероприятий. Вдобавок каждый из участников соотнесен с регионом, к которому он принадлежит. Схематически эти отношения представлены на рисунке 1.

Рисунок 1. Схема взаимосвязей объектов
Схема взаимосвязей объектов

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

Рисунок 2. Документ мероприятия с многозначными полями
Документ мероприятия с многозначными полями

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

Если же хранить данные в отдельных независимых документах, будет сложно объединять данные из этих документов в одной строке представления, используя стандартные методы приложений Lotus Domino.

Используя функции интеграции Lotus Domino и DB2, можно реализовать независимость данных путем их хранения в отдельных документах, когда это уместно, но при этом иметь возможность объединять данные в одной строке представления, когда это необходимо.

Например, можно задать связанные с темой данные, характерные для каждого мероприятия, в отдельной форме Agenda Item и связанные с участником данные, характерные для каждого мероприятия – в отдельной форме Attendee. Для обратного связывания информации о теме и участнике с мероприятием можно использовать уникальный для каждого мероприятия ключ и сохранять эти данные в каждом документе Agenda Item и Attendee.

Схематически эти отношения представлены на рисунке 3.

Рисунок 3. Измененная схема взаимосвязи объектов
Измененная схема взаимосвязи объектов

Мы по-прежнему можем заполнять формы мероприятий с отображением тем и участников, но теперь информация о каждом мероприятии agenda и о каждом участнике attendee хранится в отдельных документах и отображается в форме Events с помощью встроенных представлений. В примере, показанном на рисунке 4, обратите внимание, что теперь имеется поле Event Key. Когда пользователь нажимает кнопку для добавления элемента Agenda Item, создается новый документ, наследующий этот ключ Event. Встроенное представление содержит все записи элементов agenda, категоризируемые по ключу Event, но сконфигурировано для отображения одной категории – той категории, которая соответствует ключу Event текущего документа.

Рисунок 4. Документ мероприятия со встроенным представлением
Документ мероприятия со встроенным представлением

Для создания представления, которое может объединять данные из различных документов в одной строке представления, можно использовать комбинацию представлений доступа DB2 (для экспонирования данных из DB2) и представлений запроса (для использования операторов SQL и извлечения данных в представления Lotus Notes). Для получения дополнительной информации по созданию представлений доступа DB2 и представлений запроса SQL обратитесь к справочной системе Lotus Domino 8 Designer Help.

В нашем первом примере для каждой из трех форм Event, AgendaItem и Attendee создается представление доступа DB2. Обратите внимание на галочки рядом с некоторыми полями на рисунке 5. Это поля, которые, вероятно, будут использоваться в критерии отбора представления запроса. Галочки указывают, что данные поля будут индексироваться в DB2, что сделает извлечение данных более эффективным (подробнее см. ниже).

Рисунок 5. Представления доступа DB2 в Lotus Domino Designer
Представления доступа DB2 в Lotus Domino Designer

Данный выбор дает три представления, показанные на рисунке 6, которые можно просмотреть в центре управления DB2.

Рисунок 6. Представления доступа DB2, отображенные в центре управления DB2
Представления доступа DB2, отображенные в центре управления DB2

Обратите внимание, здесь присутствуют и таблицы представлений DB2 (имеющие индекс _T и _X в имени таблицы), и представления DB2, соответствующие представлениям доступа DB2. Любой доступ к данным, экспонируемым через представление доступа DB2, должен всегда осуществляться через представления DB2, а не через таблицы DB2, потому что именно представления DB2 содержат триггеры безопасности, обеспечивающие доступ для сервера Lotus Domino.

Затем оператором SQL SELECT, показанным в коде листинга 1, создается представление SQL-запроса.

Листинг 1. Создание представления запроса SQL
MySchema := @DB2Schema(@DbName);

"SELECT ATTENDEES.ATTENDEENAME, ATTENDEES.REGION, AGENDA.TOPICNAME, EVENTS.EVENTDATE, 
EVENTS.EVENTNAME,  EVENTS.#NOTEID FROM "

+ MySchema + ".ATTENDEES AS ATTENDEES, "
+ MySchema + ".EVENTS AS EVENTS, "
+ MySchema + ".AGENDAITEMS AS AGENDA "

+ "WHERE ATTENDEES.EVENTKEY = AGENDA.EVENTKEY AND AGENDA.EVENTKEY = 
EVENTS.EVENTKEY"

Обратите внимание, что для вычисления имени схемы, используемой для представлений, используется @DB2Schema, так что это имя не приходится указывать непосредственно в запросе. Схема является уникальной для каждого информационного массива Lotus Notes и позволяет различать представления доступа DB2 из различных баз данных, даже если они имеют одинаковые имена.

Обратите внимание на то, что выбранные поля происходят из документов трех разных типов (Attendee Name из документов Attendee, Topic Name из документов Agenda Item, а Event Date и Event Name - из документов Events).

Чтобы можно было открывать документы из представления запроса, в операторе SELECT должно быть поле #NOTEID. В оператор SELECT в листинге 1 имеется поле #NOTEID из документов Events; поэтому при двойном щелчке на строке в представлении по умолчанию откроется документ Event, который связывает участника attendee и тему.

Как уже говорилось, имя схемы необходимо для идентификации соответствующего вида DB2. Однако чтобы сделать оператор SQL более понятным, можно присвоить выбранным представлениям псевдонимы с помощью AS. Таким образом, вместо того, чтобы использовать <MySchema>.ATTENDEES на псевдоним ATTENDEES.

Наконец, наш оператор SQL применяет WHERE для соединения трех таблиц на основе сопоставления полей EventKey. Это показывает, как можно создать в представлении строку, содержащую поля из различных документов. Обратите внимание, что EventKey было одним из полей, к которому мы создали индекс DB2. Это позволяет эффективно выполнять поиск в DB2 и возвращать записи с соответствующими полями EventKey.

Можно использовать инструмент SQL Assist из центра управления DB2 для конструирования необходимого оператора SQL и проверки получаемых результатов. Обратите внимание на то, что, как показано на рисунке 7, запрос извлекает документы, соответствующие одному мероприятию (один документ мероприятия, четыре документа участника, три документа темы), и предоставляет все возможные комбинации документов в виде отдельных строк.

Рисунок 7. Результаты запроса SQL в представлении центра управления DB2
Результаты запроса SQL в представлении центра управления DB2

Результат запроса DB2, показанный на рисунке 7, можно представить в Lotus Notes путем добавления столбцов с соответствующими именами. Кроме того, представление в Lotus Notes можно упорядочивать, классифицировать и форматировать с помощью стандартных свойств видов и столбцов Lotus Notes, как показано на рисунке 8.

Рисунок 8. Представление Lotus Notes, упорядоченное по региону и участнику
Представление Lotus Notes, упорядоченное по регионам и участникам

Независимость данных дает гораздо больше гибкости для упорядочивания и классификации. Например, мы можем захотеть рассылать приглашения местным участникам при проведении мероприятия в их регионе. В нашу подборку можно добавить представление доступа DB2 Participant, как показано на рисунке 9.

Рисунок 9. Представление доступа DB2 Participant
Представление доступа DB2 Participant

Затем можно написать запрос SQL как показано в листинге 2 для соединения событий с потенциальными участниками.

Листинг 2. Создание запроса SQL для связывания мероприятий с потенциальными участниками
MySchema := @DB2Schema(@DbName);

"SELECT  "

+ "EVENTS.EVENTNAME || ' - ' || CHAR(EVENTS.EVENTDATE) AS EVENT, "

+ "PARTICIPANT.#NOTEID, PARTICIPANT.EMPLOYEE FROM "

+ MySchema + ".EVENTS AS EVENTS, "
+ MySchema + ".PARTICIPANT AS PARTICIPANT "

+ "WHERE EVENTS.REGION = PARTICIPANT.DEPARTMENT"

Необходимо различать отдельные экземпляры повторяющихся мероприятий, поэтому данный запрос соединяет поля EventName и EventDate, используя функцию конкатенации. Обратите внимание, что, поскольку EventDate является полем данных, перед тем, как его конкатенировать, необходимо преобразовать его в текстовое поле. Для отображения данного составного значения в представлении необходимо дать ему псевдоним, EVENT. Этот псевдоним используется в формуле столбца представления для группирования потенциальных приглашенных.

На этот раз мы включили #NOTEID из представления доступа DB2 Participant, что позволяет открывать записи участника двойным щелчком на строке в представлении.

Полученное представление выглядит так, как показано на рисунке 10.

Рисунок 10. Представление запроса Lotus Notes, показывающее мероприятия с потенциальными приглашенными
Представление запроса Lotus Notes, показывающее мероприятия с потенциальными приглашенными

Можно было бы отдельно выбрать в запросе EventName и EventDate и использовать формулу столбца Lotus Notes вроде EventName + “-” + EventDate. Но эффективнее выполнить конкатенацию в DB2 и просто отобразить полученный результат в представлении Lotus Notes.

Если бы мы хранили более подробную информацию о профилях участников (например, темы, которыми они интересуются), можно было бы использовать более сложную конструкцию WHERE, которая сравнивала бы интересы участников с запланированными темами повестки дня и перечисляла только участников с соответствующими интересами.


Второй сценарий: использование динамических представлений запроса для повышения эффективности приложения

По мере добавления данных в приложение вывод формы Event со встроенными представлениями будет занимать все больше и больше времени. Это связано с тем, что для представления одной категории во встроенном представлении клиент Lotus Notes сначала извлекает все классифицированное представление, а потом - нужную категорию. Гораздо эффективнее извлекать только записи, соответствующие требуемой категории.

Поскольку наше приложение использует DB2, вместо стандартных представлений Lotus Notes можно создать встроенные представления, использующие представления запроса с динамически создаваемыми SQL-запросами.

Стандартные представления Lotus Notes не позволяют передавать параметры в формулу отбора представления во время извлечении представления. Однако для представлений запроса имеется три основных способа изменения запроса SQL во время извлечения представления.

Во-первых, запрос SQL может искать информацию в других документах или представлениях Lotus Notes (например, документах профилей) или считывать значения из переменных среды. В приведенном ниже примере для события PostOpen в форме Event задан код, в результате работы которого при открытии каждого документа встроенные представления по ключу мероприятия определяют того, записи каких тем и участников нужно извлекать.

Код LotusScript® в листинге 3 устанавливает для переменной среды EventkeyENV значение, равное значению поля EventKey.

Листинг 3. Установка переменной среды
Sub Postopen(Source As Notesuidocument)
	Dim session As New NotesSession
	Call session.SetEnvironmentVar _
	("EventKeyENV",source.FieldGetText("EventKey"))
End Sub

Запрос SQL, показанный в листинге 4, извлекает переменную среды EventKeyENV и использует ее значение в конструкции WHERE оператора SQL для извлечения только записей с соответствующим ключом Event.

Листинг 4. Извлечение переменной среды
MySchema := @DB2Schema(@DbName);
Keyword := @Environment("EventKeyENV");

"SELECT * FROM " + MySchema + ".ATTENDEES AS ATTENDEES WHERE ATTENDEES.EVENTKEY =
 '" + Keyword + "'"

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

Обратите внимание, что напрямую использовать значение поля ключа Event документа в запросе SQL невозможно, поскольку встроенное представление не видит содержимого документа, в котором оно отображается.

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

Например, имеется представление запроса, группирующее Attendees (участников) по Topic (теме), как показано на рисунке 11.

Рисунок 11. Представление запроса, группирующего Представление запроса, группирующее участников по темам
Представление запроса, группирующего Представление запроса, группирующее участников по темам

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

Это можно сделать, добавив в запрос SQL функцию @Prompt для ввода пользователям интересующей темы, а затем добавив эту тему в конструкцию WHERE в операторе SQL, как показано в SQL-запросе листинга 5.

Листинг 5. Добавление функции @Prompt
MySchema := @DB2Schema(@DbName);

TopicChoice := @Prompt([OkCancelEdit]; "Topic Name"; "Enter topic name";"");

"SELECT AGENDA.TOPICNAME, ATTENDEES.ATTENDEENAME, EVENTS.EVENTDATE, EVENTS.EVENTNAME, 
EVENTS.#NOTEID FROM " + MySchema + ".ATTENDEES AS ATTENDEES, " + MySchema + 
".EVENTS AS EVENTS, " + MySchema + ".AGENDAITEMS AS AGENDA WHERE ATTENDEES.EVENTKEY =
AGENDA.EVENTKEY AND AGENDA.EVENTKEY = EVENTS.EVENTKEY  AND "

+ "AGENDA.TOPICNAME = '" + TopicChoice + "'"

Когда пользователь выбирает это представление, ему предлагается ввести название интересующей темы, как показано на рисунке 12. В данном случае пользователь вводит в поле темы Notes 8 Client.

Рисунок 12. Пользователю предлагается ввести наименование темы
Пользователю предлагается ввести наименование темы

Выдаются только те записи, которые соответствуют теме, Notes 8 Client, как показано на рисунке 13.

Рисунок 13. Представление Lotus Notes, отображающее только те записи, которые соответствуют выбранной теме
Представление Lotus Notes, отображающее только те записи, которые соответствуют выбранной теме

Обратите внимание, что функция @Prompt позволяет представить пользователю список для выбора тем, чтобы гарантировать допустимость вводимых данных. Для выбора другого наименования темы пользователь может обновить представление, нажав F5 (или F9), при этом снова отобразится диалоговое окно с запросом.

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

Третьим способом динамической модификации SQL является замена значений URL.

Можно использовать функцию @URLQueryString для извлечения информации из текущего URL и модификации представления запроса.

Например, если рассмотреть Web-версию представления, запрашивающего у пользователя имя участника для отображения соответствующих записей, можно с помощью показанного в листинге 6 запроса SQL извлечь значение, заданное для параметра Attendee в URL, и использовать его при отборе записей.

Листинг 6. Применение запроса SQL с функцией @URLQueryString
MySchema := @DB2Schema(@DbName);

AttendeeChoice := @UrlQueryString("Attendee");

"SELECT ATTENDEES.ATTENDEENAME, AGENDA.TOPICNAME, EVENTS.EVENTDATE, EVENTS.EVENTNAME, 
EVENTS.#NOTEID FROM " + MySchema + ".ATTENDEES AS ATTENDEES, " + MySchema + 
".EVENTS AS EVENTS, " + MySchema + ".AGENDAITEMS AS AGENDA WHERE ATTENDEES.EVENTKEY = 
AGENDA.EVENTKEY AND AGENDA.EVENTKEY = EVENTS.EVENTKEY AND ATTENDEES.ATTENDEENAME = 
'" + AttendeeChoice + "'"

В результате пользователь, введя приведенный ниже URL или нажав на порождающую его ссылку, увидит записи, показанные на рисунке 14:

http://domino.betaworks.ibm.com/db2example/events.nsf/WebTopics?OpenView&Attendee=Frank%20Adams
Рисунок 14. Web-представление запроса тем по участнику
Web-представление запроса тем по участнику

Вдобавок к вышеуказанным примерам использование представлений SQL-запросов вместо стандартных представлений Lotus Notes в других областях также позволяет повысить производительность.

Во-первых, стандартные представления Lotus Notes в базе данных Lotus Domino поддерживаются и обновляются сервером Lotus Domino. Если база данных работает на DB2, индексы этих представлений будут физически храниться на сервере DB2, но поддерживать и обновлять их будет сервер Lotus Domino. Если индексы представления большие, а данные в приложении часто меняются, серверу Lotus Domino придется расходовать значительные ресурсы для поддержания актуальности индексов представлений.

С другой стороны, сервер Lotus Domino не отвечает за поддержку индексов в представлениях запроса; этими индексами управляет сервер DB2. Поэтому в среде, в которой сервер Lotus Domino и сервер DB2 размещаются на разных аппаратных устройствах, использование представлений запроса вместо стандартных представлений Lotus Notes может значительно снизить нагрузку на сервер Lotus Domino. Кроме того, когда пользователь открывает стандартное представление Lotus Notes, серверу Lotus Domino приходится обновлять индексы представления перед отображением самого представления. В операторе DB2 индексы обновляются при каждом добавлении, обновлении и удалении документа, так что необходимости выполнять обновление индекса перед запуском оператора SQL нет. Это ускоряет извлечение данных.

Во вторых, традиционные приложения Lotus Notes могут содержать большое количество представлений, поскольку пользователям необходимо сортировать и группировать одни и те же наборы данных различными способами. Нередко приложение создается с 10 представлениями и 5000 документов и через несколько лет содержит 500 представлений и 500000 документов. Задача UPDATE/UPDALL на сервере Lotus Domino может серьезно влиять на производительность сервера Lotus Domino, поскольку она стремится поддерживать актуальность всех индексов представления.

Функции интеграции Lotus Domino и DB2 позволяют значительно уменьшить количество представлений, соответствующих приложению, путем замены группы стандартных представлений на одно динамическое представление запроса. В предыдущем примере была показана замена значения: содержание представления определяется согласно соответствующему наименованию темы. Можно также заменять целые части запроса SQL, как показано в листинге 7.

Листинг 7. Замещение части запроса SQL
MySchema := @DB2Schema(@DbName);

CategoryChoice := @Prompt([OkCancelList]; "Category"; "Select category";""; 
"Topic":"Attendee");

CategoryCol := @If(CategoryChoice = "Topic"; "AGENDA.TOPICNAME"; 
"ATTENDEES.ATTENDEENAME");

SecondCol := @If(CategoryChoice = "Topic"; "ATTENDEES.ATTENDEENAME"; 
"AGENDA.TOPICNAME");

"SELECT " + CategoryCol + " AS CATEGORY, "

+ SecondCol + " AS SECOND "

+ ", EVENTS.EVENTDATE, EVENTS.EVENTNAME, EVENTS.#NOTEID FROM " + MySchema + 
".ATTENDEES AS ATTENDEES, " + MySchema + ".EVENTS AS EVENTS, " + MySchema + 
".AGENDAITEMS AS AGENDA WHERE ATTENDEES.EVENTKEY = AGENDA.EVENTKEY AND 
AGENDA.EVENTKEY = EVENTS.EVENTKEY"

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

Затем выбранному полю присваивается псевдоним CATEGORY, а другому полю (которое в данном случае тоже необходимо отображать в виде) присваивается псевдоним SECOND. При использовании CATEGORY и SECOND в качестве имен полей первого и второго столбцов в этом представлении (имя второго столбца нужно оставить незаполненным), это же представление отображается так, как показано на рисунке 15, если пользователь выбрал в качестве категории Topic (тему).

Рисунок 15. Представление Lotus Notes при выборе пользователем категории Topic (тема)
Представление Lotus Notes при выборе пользователем категории Topic (тема)

Если пользователь выбирает в качестве категории Attendee (участник), это же представление выглядит, как показано на рисунке 16.

Рисунок 16. Представление Lotus Notes при выборе пользователем категории Attendee (участник)
Представление Lotus Notes при выборе пользователем категории Attendee (участник)

В данном примере одно представление SQL-запроса заменило функции двух стандартных представлений NSF.


Третий сценарий: распространение приложения на несколько баз данных

Многие организации разрабатывают важные для них приложения Lotus Domino, которые затем используются многие годы, в течение которых в приложения добавляется все больше и больше данных. По мере увеличения размера приложения его производительность может снижаться, и приложение становится трудно эксплуатировать. Как было описано в предыдущем разделе, использование представлений запроса вместо стандартных представлений Lotus Notes может улучшить производительность и сократить размеры индексов представления, соответствующих приложению. Недавно один заказчик сообщил, что ему удалось уменьшить размер приложения на 40 процентов путем замены стандартных представлений Lotus Notes на представления запроса. Однако для приложения, содержащего большой объем данных, такого уменьшения может быть недостаточно.

Хранение данных приложения Lotus Domino в DB2 не означает, что одна база данных Lotus Domino может разрастись больше существующего предела для NSF (64 ГБ). Однако функции интеграции Lotus Domino и DB2 позволяют организовать более эффективное управление большими приложениями и увеличить суммарный объем данных приложения сверх этого предела.

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

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

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

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

Рисунок 17. Lotus Notes отображает записи о посетителях мероприятия из текущей базы данных
Lotus Notes отображает записи о посетителях мероприятия из текущей базы данных

В архивной базе данных за 2007 год представление такое, как показано на рисунке 18.

Рисунок 18. Lotus Notes отображает записи о посетителях мероприятия из архивной базы данных
Lotus Notes отображает записи о посетителях мероприятия из архивной базы данных

В текущей базе данных можно создать вид запроса, объединяющий записи из обеих баз данных с использованием запроса SQL, как показано в листинге 8.

Листинг 8. Объединение записей из обеих баз данных
MySchema := @DB2Schema(@DbName);
ArchSchema := @DB2Schema("":"DB2Example\\events2007.nsf");
AttendeeChoice := @Prompt([OkCancelEdit]; "AttendeeName"; "Enter attendee name";"");

"SELECT ATTENDEES.ATTENDEENAME, AGENDA.TOPICNAME, EVENTS.EVENTDATE, 
EVENTS.EVENTNAME, EVENTS.#NOTEID FROM " + MySchema + ".ATTENDEES AS ATTENDEES, " + 
MySchema + ".EVENTS AS EVENTS, " + MySchema + ".AGENDAITEMS AS AGENDA WHERE 
ATTENDEES.EVENTKEY = AGENDA.EVENTKEY AND AGENDA.EVENTKEY = EVENTS.EVENTKEY 
AND ATTENDEES.ATTENDEENAME = '" + AttendeeChoice + "'" +

" UNION SELECT ATTENDEES.ATTENDEENAME, AGENDA.TOPICNAME, EVENTS.EVENTDATE, 
EVENTS.EVENTNAME, EVENTS.#NOTEID FROM " + ArchSchema + ".ATTENDEES AS ATTENDEES, " + 
ArchSchema + ".EVENTS AS EVENTS, " + ArchSchema + ".AGENDAITEMS AS AGENDA WHERE 
ATTENDEES.EVENTKEY = AGENDA.EVENTKEY AND AGENDA.EVENTKEY = EVENTS.EVENTKEY 
AND ATTENDEES.ATTENDEENAME = '" + AttendeeChoice + "'"

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

Также обратите внимание на то, что оператор SQL использует UNION для объединения двух наборов записей.

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

Рисунок 19. Lotus Notes, отображающий записи о посетителях события из обеих баз данных
Lotus Notes, отображающий записи о посетителях события из обеих баз данных

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

В представлении доступа DB2 можно хранить специальные поля, помогающие идентифицировать расположение документа-источника. В данном случае мы используем следующие поля:

  • #DBPATH, указывающее путь доступа к файлу и директорию базы данных в которой размещается представление доступа DB2
  • #SERVER -- имя сервера, на котором хранится база данных
  • #UNID -- уникальный идентификатор документа, соответствующий каждой записи в представлении доступа DB2

См. рисунок 20.

Рисунок 20. Специальные поля, предусмотренные для представлений доступа DB2
Специальные поля, предусмотренные для представлений доступа DB2

При добавлении этих специальных полей в представление доступа DB2 теперь эту дополнительную информацию можно увидеть в представлении DB2, как показано на рисунке 21.

Рисунок 21. Представление доступа DB2 со специальными полями, отображенными в центре управления DB2
Представление доступа DB2 со специальными полями, отображенными в центре управления DB2

С помощью этой информации можно настроить событие QueryOpenDocument на поиск и открытие соответствующего документа.

Для извлечения этих новых полей в запросе SQL можно использовать SQL, показанный в листинге 9.

Листинг 9. Извлечение новых полей в запросе SQL
MySchema := @DB2Schema(@DbName);
ArchSchema := @DB2Schema("":"DB2Example\\events2007.nsf");
AttendeeChoice := @Prompt([OkCancelEdit]; "AttendeeName"; "Enter attendee name";"");

"SELECT ATTENDEES.ATTENDEENAME, AGENDA.TOPICNAME, EVENTS.EVENTDATE, 
EVENTS.EVENTNAME, EVENTS.#NOTEID," +

" EVENTS.#SERVER || '~' || EVENTS.#DBPATH || '~' || EVENTS.#UNID AS DOCID " +

"FROM " + MySchema + ".ATTENDEES AS ATTENDEES, " + MySchema + ".EVENTS AS EVENTS, " + 
MySchema + ".AGENDAITEMS AS AGENDA WHERE ATTENDEES.EVENTKEY = AGENDA.EVENTKEY 
AND AGENDA.EVENTKEY = EVENTS.EVENTKEY AND ATTENDEES.ATTENDEENAME = '" + 
AttendeeChoice + "'" +

" UNION SELECT ATTENDEES.ATTENDEENAME, AGENDA.TOPICNAME, EVENTS.EVENTDATE, 
EVENTS.EVENTNAME, EVENTS.#NOTEID, EVENTS.#SERVER || '~' || EVENTS.#DBPATH || '~' || 
EVENTS.#UNID AS DOCID FROM " + ArchSchema + ".ATTENDEES AS ATTENDEES, " + ArchSchema + 
".EVENTS AS EVENTS, " + ArchSchema + ".AGENDAITEMS AS AGENDA WHERE 
ATTENDEES.EVENTKEY = AGENDA.EVENTKEY AND AGENDA.EVENTKEY = EVENTS.EVENTKEY 
AND ATTENDEES.ATTENDEENAME = '" + AttendeeChoice + "'"

Обратите внимание, что новые поля конкатенируются в единое поле идентификатора документа, которому присвоено псевдоним DOCID.

Поскольку локального внутреннего документа, соответствующего записям, ссылающимся на документы в другой базе данных, нет, возможность манипулировать значениями, отображенными в представлении, ограничена. Единственным свойством LotusScript, которое можно использовать, является свойство CaretCategory класса NotesUIView. Это свойство выдает текущую категорию выбранного документа.

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

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

Рисунок 22. Первый столбец представления Lotus Notes
Первый столбец представления Lotus Notes

Код, показанный в листинге 10, можно ввести в событие Queryopendocument нашего представления, чтобы обеспечить нахождение и открытие нужного документа при двойном щелчке по строке в представлении:

Листинг 10. Реализация поиска и открытия нужного документа
Sub Queryopendocument(Source As Notesuiview, Continue As Variant)
	continue = False
	Dim ws As New NotesUIWorkspace	
	Dim db As New NotesDatabase("","")	
	Dim target As String
	Dim server As String
	Dim path As String
	Dim unid As String
	
	target = Source.CaretCategory
	
	server = Strleft(target, "~")
	path = Strleft(Strright(target, "~"), "~")	
	unid = Strrightback(target, "~")
	
	Call db.Open(server, path)
	Set originalDoc = db.GetDocumentByUNID ( unid )
	
	Set uidoc = ws.EditDocument(False, originalDoc, False, "", False, True)
	
End Sub

Если убрать категоризацию из столбца Attendee и скрыть новый первый столбец, представление будет выглядеть, как показано на рисунке 23. При нажатии пользователем на любую строку в этом представлении открывается нужный документ, независимо от того, в какой базе данных он хранится.

Рисунок 23. Представление Lotus Notes со скрытым первым столбцом
Представление Lotus Notes со скрытым первым столбцом

Четвертый сценарий: составление отчетности по данным Lotus Notes

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

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

Например, на рисунке 24 показано стандартное представление Lotus Notes, суммирующее все расходы для мероприятий в каждом регионе, посещенных соответствующими участниками, путем группирования всех документов мероприятия по Attendee (участнику) и Region (региону), а также добавления итоговых данных в колонку Cost (расходы).

Рисунок 24. Представление Lotus Notes, использующее стандартную функцию суммирования столбца
Представление Lotus Notes, использующее стандартную функцию суммирования столбца

Если нужно выполнить только отчетность по суммарным расходам на мероприятия для каждого пользователя, вместо извлечения всех посещенных мероприятий можно использовать запрос SQL, как показано в листинге 11.

Листинг 11. Использование запроса SQL для выполнения отчетности по суммарным расходам
MySchema := @DB2Schema(@DbName);

"SELECT ATTENDEES.ATTENDEENAME, ATTENDEES.REGION, "

+ "SUM(EVENTS.COST) AS SUM "

+ "FROM " + MySchema + ".ATTENDEES AS ATTENDEES, " + MySchema + ".EVENTS AS EVENTS 
WHERE ATTENDEES.EVENTKEY =  EVENTS.EVENTKEY "

+ "GROUP BY ATTENDEES.REGION, ATTENDEES.ATTENDEENAME"

Обратите внимание, что вместо выбора поля EVENTS.COST теперь к коду добавлена функция SUM. Совместно с функцией SUM необходимо добавить конструкцию GROUP BY, сообщающую запросу SQL, какие группы значений EVENTS.COST нужно суммировать.

Затем мы используем SUM, псевдоним, данный SUM(EVENTS.COST), в качестве значения поля в столбце Cost. Обратите внимание, что если необходимо отобразить сводные итоговые данные по Region (региону) в том же представлении, то можно по-прежнему использовать стандартную функцию суммирования итога представления, но теперь итоговые данные будут рассчитываться исходя из предварительно агрегированных суммарных расходов по участникам.

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

Рисунок 25. Представление Lotus Notes, использующее запрос SQL для расчета суммарных расходов
Представление Lotus Notes, использующее запрос SQL для расчета суммарных расходов

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

Листинг 12. Более эффективное извлечение необходимых данных
MySchema := @DB2Schema(@DbName);

"SELECT DISTINCT EVENTS.EVENTNAME,  ATTENDEES.REGION FROM "

+ MySchema + ".ATTENDEES AS ATTENDEES, "
+ MySchema + ".EVENTS AS EVENTS "

+ "WHERE ATTENDEES.EVENTKEY = EVENTS.EVENTKEY"

Обратите внимание на параметр DISTINCT, следующий за параметром SELECT. Этот параметр позволяет вызвать одну строку для каждого мероприятия, посещенного хотя бы одним участником из региона, как показано на рисунке 26.

Рисунок 26. Представление Lotus Notes, отображающее посещаемость мероприятий по регионам
Представление Lotus Notes, отображающее посещаемость мероприятий по регионам

Два предыдущих примера демонстрируют, как функции DB2 позволяют получать такие же результаты, что и стандартное представление Lotus Notes, но гораздо эффективнее. Библиотека функций DB2 также содержит много функций, позволяющих создавать отчетность по данным Lotus Notes такими способами, которые невозможны при использовании стандартного представления Lotus Notes. Например, запрос, показанный в листинге 13, использует функцию агрегации для получения статистической информации о посещенных мероприятиях по каждому региону.

Листинг 13. Использование функции агрегирования
MySchema := @DB2Schema(@DbName);

"SELECT COUNT(EVENTS.COST) AS COUNT, SUM(EVENTS.COST) AS SUM, AVG(EVENTS.COST) 
AS AVG, MAX(EVENTS.COST) AS MAX, MIN(EVENTS.COST) AS MIN, ATTENDEES.REGION FROM "

+ MySchema + ".ATTENDEES AS ATTENDEES, "
+ MySchema + ".EVENTS AS EVENTS "

+ "WHERE ATTENDEES.EVENTKEY = EVENTS.EVENTKEY"

+ " GROUP BY ATTENDEES.REGION"

Результаты этого запроса SQL можно отобразить в представлении, показанном на рисунке 27, используя заданные псевдонимы (COUNT, SUM, AVG, MAX, MIN) в качестве полей столбцов.

Рисунок 27. Представление Lotus Notes, отображающее агрегированную статистику мероприятий по регионам
Представление Lotus Notes, отображающее агрегированную статистику мероприятий по регионам

В одном из предыдущих сценариев мы использовали функцию конкатенации строк "||" для создания единого поля идентификатора для документа.

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

В предыдущих примерах было показано, как составлять сводные отчеты в приложении Lotus Notes, но, как говорилось во Введении, к тем же данные можно организовать динамический доступ в приложении электронной таблицы или в стороннем продукте по созданию отчетов, например, Crystal Reports (используя прямое соединение JDBC с данными, содержащимися в DB2). Данный подход позволяет использовать любые встроенные возможности этих программ по созданию графиков и отчетов для составления отчетов по данным, хранящимся в приложениях Lotus Notes.


Заключение

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

В данном документе резюмируются четыре основных сценария, по которым можно использовать функции интеграции Lotus Domino и DB2 для совершенствования функциональности или производительности чистых приложений Lotus Domino. Использованные здесь методы можно сочетать и расширять для построения более сложных приложений.

Важно отметить, что описанные в данной статье функции доступны только в приложениях, работающих на сервере с DB2. Если же приложение, содержащее какую-либо из данных функций, реплицируется на сервер, не включающий DB2, или в клиент Lotus Notes, то структура приложения копируется, однако попытка использовать какую-либо из функций (например, открытие представления запроса) заканчивается ошибкой, и никакие данные не отображаются.


Дополнение: пример приложения

Для запуска примера приложения без изменений необходимо выполнить следующее:

  1. Установите сервер Lotus Domino 8 и DB2 9.1 FP2, настройте DB2 Access Server, как описано здесь. Убедитесь, что были выполнены все шаги, относящиеся к использованию представлений доступа DB2 и представлений SQL- запросов с приложениями Domino.
  2. Скопируйте базы данных (EVENTS.NSF и EVENTS2007.NSF) в каталог DB2Example на сервере Lotus Domino и (если форматом базы данных по умолчанию является NSF, а не DB2) введите с консоли сервера следующие команды:

    load compact -p DB2Example\events.nsf
    load compact -p DB2Example\events2007.nsf

    Эти команды конвертируют базы данных для использования хранилища данных DB2..

  3. Откройте каждую базу данных в Lotus Domino Designer и перейдите в Shared Resources - DB2 Access Views. Выберите по очереди каждое представление доступа DB2 и выполните следующие действия:
    • Создайте/обновите действующую DB2
    • Заполните DB2
    • Обновите статус

Когда все представления DB2access будут обработаны, напротив них появится зеленая пиктограмма, как показано на рисунке A1.

Рисунок A1. Отображение обработки представлений доступа DB2 в Domino Designer
Отображение обработки представлений доступа DB2 в Domino Designer

Теперь приложение готово к работе.

Обратите внимание, что если базы данных находятся не в директории DB2Example, как было описано выше, то необходимо будет скорректировать запрос SQL в представлении “03-All Topics by Attendee-with prompt”, указав путь к хранилищу для базы данных EVENTS2007.

Описание представлений

Основное приложение EVENTS.NSF содержит представления, показанные на рисунке A2. Они пронумерованы согласно сценарию, который они иллюстрируют.

EVENTS2007.NSF содержит подгруппу этих представлений.

Рисунок A2. Отображение всех доступных представлений базы данных Events (мероприятия) в навигаторе
Отображение всех доступных представлений базы данных Events (мероприятия) в навигаторе

Дополнительные примечания

  • • Представления 00 – это стандартные представления NSF для облегчения размещения записей.
  • • Представления 02a используются в качестве встроенных представлений в форме Events (мероприятия). Они изначально пусты, если открыть их из основного навигатора, а после открытия документа Event (мероприятие) они отображают Attendees (участников) и Topics (темы), соответствующие Event (мероприятию). Конечно, эти представления обычно будут скрыты, но они показаны для облегчения идентификации.
  • • Представления 02b и 02c указывают на имя темы и участника соответственно. Обратите внимание, что для того, чтобы сделать запрос максимально простым, поиск ведется с учетом регистра.
  • • Представление 02d отображается пустым в клиенте Lotus Notes; однако при обращении к приложению через HTTP с использованием URL, сходного с показанным в сценарии, представление в Web-браузере заполняется данными.

Загрузка

ОписаниеИмяРазмер
Образец кодаEvents.nsf448 КБ
Образец кодаEvents2007.nsf448 КБ

Ресурсы

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Lotus
ArticleID=420508
ArticleTitle=Использование функций интегрирования IBM Lotus Domino и IBM DB2 для усовершенствования приложений Lotus Domino
publish-date=08132009