Delphi. UniGUI. Правильная архитектура приложения на примере создания соединения с базой данных MySQL с помощью FireDAC

Интересное обсуждение у меня сложилось на форуме UniGUI, когда я не смог передать ссылку на объект так как я это делаю обычно, в Delphi (через свойства или через параметр Sender). Вот ссылка на само обсуждение

http://forums.unigui.com/index.php?/topic/7556-how-to-give-correct-link-to-created-instance

Итак, в UniGUI есть 3 типа объектов

UniServer Module ( создается 1 раз и работает все время, пока работает приложение)

http://www.unigui.com/doc/online_help/server_module.htm

UniMainModule (создается 1 раз и работает в течение сессии – о том, что такое сессия в UniGUI можно узнать в другом моем посте – и это не тоже самое, что сессия в PHP )

http://www.unigui.com/doc/online_help/main_module.htm

Все остальное – работает от создания до закрытия. Например формы. Создали – она держится в памяти – закрыли – уносит все данные с собой. В этом смысле UniMainModule это вроде как глобальный юнит, к которому можно обратиться, например как UniMainModule.doSomething, и также к UniServerModule.doSomething.

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

Разберем пример соединения с базой данных

Я сразу покажу как правильно с точки зрения автора фрэймворка Farshad Mojaheri и почему так правильно. Ну а далее вы можете сделать как Вам удобно. Итак, для соединения с БД будем использовать технологию FireDAC.

Итак, у нас имеется MySQL, FireDAC, Delphi XE Seattle

Проблема 1 – где хранить libmysql.dll и как программе показывать где находится библиотека?

Как известно, для работы с БД MySQL из Delphi нужен файл libmysql.dll.

Также известно, что FireDAC поддерживает 3 типа соединений

-Persistent

-Private

-Temporary

Более подробно про виды соединений в FireDAC здесь

Также известно, что UniGUI приложение можно откомпилировать как EXE и как DLL для запуска на IIS.

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

А вот случай с DLL интереснее. Тут уже непонятно куда положить файл libmysql.dll, так, чтобы приложение его нашло. Можно пробовать в С:\Windows\System32 или c:\windows\SysWow64\

Но это такой путь, не универсальный, где-то он сработает а где-то нет. Мне хотелось научиться делать это более менее универсально. То есть хранить файлы в произвольной папке, скажем в C:\MySQLDriver и просто показывать приложению, что libmysql.dll нужно искать именно там. Ну, кто ищет, тот найдет. И вот оказывается в FireDAC есть такая замечательная вещь как Persistent и Private подключения, которые пользуются файлами

FDConnectionDefs.ini – хранит в себе настройки подключения – имя БД, пароль, сервер, порт и др.

FDDrivers.ini – хранит в себе имена и пути до драйверов

Итак, что можно сделать? В FDConnectionDefs.ini добавить набор настроек, например так

В FDDrivers.ini сделать виртуальный драйвер

И такой подход полностью избавит от зависимости от хранения libmysql.dll в папке проекта, и тогда в случае компиляции UniGUI проекта в DLL – можно будет просто указать в качестве папки для хранения Libmysql.dll папку C:\MySQLDriver

Проблема 2 – где хранить FDManager?

Чтобы указывать приложению где находятся файлы FDConnectionDefs.ini и FDDrivers.ini нужен компонент FDManager, в свойствах которого мы прописываем пути к соответствующим файлам.

41

Сначала я пробовал хранить этот компонент в uDBConnection модуле, но при запуске приложение ругалось на то, что только 1 FD Manager должен быть на все приложение. В результате обсуждения на форуме пришли к выводу, что лучше его хранить на сервере.  Когда я перенес его на серверную часть – все встало на свои места.

Проблема № 3 – как подключаться?

Здесь я приведу 2 метода – первый подключает приложение к базе данных, если libmysql.dll лежит в папке с проектом, второй же – если libmysql.dll лежит в папке, определенной в FDDrivers.ini, который в свою очередь используется в одном из определений файла FDConnectionDefs.ini

 

Итак, метод первый – для случая, если libmysql.dll лежит в той же папке что и EXE файл

Метод 2 для случая, если файл libmysql.dll лежит в произвольной папке

Для начала создаем определение соединения

Далее собственно пробуем соединяться

Проблема 4 – где хранить остальные элементы подключения?

Вариант 1 – через Free DataModule и создание экземпляра класса в UniMainModule

Как известно, Free DataModule в UniGUI – это аналог традиционного TDataModule в Delphi. Здесь ручное управление памятью. Сами его создали и сами можем уничтожить.

Итак, нам потребуется отдельный модуль uDBConnection с методами подключения и следующими компонентами

42

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

Лучшим местом для создания экземпляра класса будет UniMainModule – так как данный модуль, сам по себе работает на протяжении сессии в UniGUI, то есть, например так…

Единственный момент – если произошла какая-то ошибка – нигде об этом не сообщается. По крайней мере этого не видно, но в случае создания соединение в MainForm, об ошибке будет сообщено в браузере.

Вариант 2 – через Application DataModule

Этот дата модуль создается автоматически вместе с сессией и уничтожается, чтобы его использовать в UniMainModule нужно добавить в его uses ссылку на наш модуль uDBConnection

И тогда не нужно ничего создавать и уничтожать, из любого модуля сможем обратиться как

 

Что дальше? Тестируем работу приложения.

Для теста я сделал вот такой простой код, который повесил на кнопку

43

This entry was posted in Delphi, FireDAC, UniGui. Bookmark the permalink.

Leave a Reply