Разработка практически любого программного продукта требует наличия как минимум одной базы данных. Для взаимодействия с ней из программы необходимо написание SQL-запросов, что при частом обращении к БД является причиной для написания большого количества кода, часто однообразного и подверженного ошибкам. Помимо этого для хранения одного объекта в БД может использоваться несколько таблиц, содержащих, например, основную и дополнительную информацию о данном объекте. А извлечение всей информации об объекте будет выглядеть в виде сложного SQL-запроса с операцией JOIN [1].
Неотъемлемой частью современного программирования являются объектно-ориентированный подход, а, значит, и объектно-ориентированные языки (C#, Java, C++ и др.). Основные понятия ООП это объект и класс. Каждый объект является значением, относящимся к определённому классу. Класс представляет собой объявленный программистом составной тип данных, имеющий в составе поля данных и методы [2].
Задачу связывания БД с концепциями ООП посредством создания виртуальной объектной БД позволяет решить технология программирования ORM.
Некоторые реализации ORM автоматически синхронизируют загруженные в память объекты с базой данных. Для того чтобы это было возможным, после создания объект-в-SQL-преобразующего SQL-запроса (класса, реализующего связь с БД) полученные данные копируются в поля объекта, как во всех других реализациях ORM. После этого объект должен следить за изменениями этих значений и записывать их в базу данных [1].
Системы управления реляционными базами данных показывают хорошую производительность на глобальных запросах, которые затрагивают большой участок базы данных, но объектно-ориентированный доступ более эффективен при работе с малыми объёмами данных, так как это позволяет сократить семантический провал между объектной и реляционной формами данных.
При одновременном существовании объектной и реляционной форм данных увеличивается сложность объектного кода для работы с реляционными базами данных, и он становится более подвержен ошибкам. Разработчики программного обеспечения, основывающегося на базах данных, искали более легкий способ достижения постоянства их объектов.
С точки зрения программиста система должна выглядеть как постоянное хранилище объектов. Он может просто создавать объекты и работать с ними как обычно, а они автоматически будут сохраняться в реляционной базе данных.
ORM избавляет программиста от написания большого количества кода, часто однообразного и подверженного ошибкам, тем самым значительно повышая скорость разработки [1]. Кроме того, большинство современных реализаций ORM позволяют программисту при необходимости самому жёстко задать код SQL-запросов, который будет использоваться при тех или иных действиях (сохранение в базу данных, загрузка, поиск и т. д.) с постоянным объектом [3].
Изначально программы писались с использованием функционального или процедурного принципа программирования. Со временем они становились всё более крупными и сложными, что доставляло проблемы разработчикам при поддержке таких программ и внесении изменений. Эту проблему решает объектно-ориентированное программирование. ООП позволяет объединить данные и методы, относящиеся к одной сущности, и работать с ними, как с одним целым [2].
ООП основывается на нескольких базовых принципах:
– абстракция — придание объекту характеристик, которые четко выделяют его на фоне остальных, определяя его концептуальные границы;
– наследование (рис. 1) — процесс, который позволяет одному объекту приобретать свойства другого объекта;
Рис. 1. Пример наследования в ООП (язык C#)
– инкапсуляция (рис. 2) — представляет собой программный механизм, который связывает данные с обрабатывающими их кодами и защищает и те, и другие от внешних воздействий и ошибочных действий;
Рис. 2. Инкапсуляции в ООП (язык C#) на примере инкапсуляции поля объекта
– полиморфизм (рис. 3) — обозначает средство, позволяющее посредством единого интерфейса получить доступ к целому классу действий.
Рис. 3. Пример перегрузки метода в ООП (язык C#)
Популярным шаблоном проектирования приложений для организации доступа к данным реляционной базы данных в ООП является Active Record (рис. 4).
Рис. 4. Пример реализации паттерна Active Record (добавление нового пользователя)
Основной принцип заключается в том, что таблицы базы данных обернуты в классы так, что объектный экземпляр привязан к единственной строке в таблице. После создания нового объекта соответствующая ему новая строка таблицы добавляется на сохранение. Любой загруженный объект получает всю необходимую информацию из БД. Если объект был изменен, то строка, соответствующая ему в таблице БД, будет также изменена. Класс обёртки реализует методы средства доступа или свойства для каждого столбца в таблице или представлении [4, 5].
Существуют уже готовые программные решения, реализующие объектно-реляционное отображение ORM. Некоторые реализации основаны на шаблоне проектирования Active Record.
EclipseLink — свободный фреймворк для языка программирования Java, предназначенный для решения задач объектно-реляционного отображения ORM [6]. Позволяет работать с разными сервисами данных, включая базы данных, веб-сервисы, Object XML mapping (OXM), и корпоративные информационные службы.
Hibernate [7] — самая популярная реализация спецификации JPA, предназначенная для решения задач объектно-реляционного отображения (ORM). Распространяется свободно на условиях GNU Lesser General Public License. Целью Hibernate является освобождение разработчика от значительного объёма сравнительно низкоуровневого программирования при работе в объектно-ориентированных средствах в реляционной базе данных. Разработчик может использовать Hibernate как в процессе проектирования системы классов и таблиц «с нуля», так и для работы с уже существующей базой данных. Библиотека не только решает задачу связи классов Java с таблицами базы данных (и типов данных Java с типами данных SQL), но и также предоставляет средства для автоматической генерации и обновления набора таблиц, построения запросов и обработки полученных данных и может значительно уменьшить время разработки, которое обычно тратится на ручное написание SQL- и JDBC-кода. Hibernate автоматизирует генерацию SQL-запросов и освобождает разработчика от ручной обработки результирующего набора данных и преобразования объектов, максимально облегчая перенос (портирование) приложения на любые базы данных SQL.
ADO.NET Entity Framework — объектно-ориентированная технология доступа к данным, является object-relational mapping (ORM) решением для.NET Framework от Microsoft. Предоставляет возможность взаимодействия с объектами как посредством LINQ в виде LINQ to Entities, так и с использованием Entity SQL. Для облегчения построения web-решений используется как ADO.NET Data Services (Astoria), так и связка из Windows Communication Foundation и Windows Presentation Foundation, позволяющая строить многоуровневые приложения, реализуя один из шаблонов проектирования MVC, MVP или MVVM [8].
NHibernate — ORM-решение для платформы Microsoft.NET, портированное с Java. Это бесплатная библиотека с открытым кодом, распространяется под лицензией GNU Lesser General Public License. NHibernate позволяет отображать объекты бизнес-логики на реляционную базу данных. По заданному XML-описанию сущностей и связей NHibernate автоматически создает SQL-запросы для загрузки и сохранения объектов [9].
Поддерживаемые СУБД:
– Microsoft SQL Server;
– Oracle;
– Microsoft Access;
– Firebird;
– PostgreSQL;
– DB2 UDB;
– MySQL;
– SQLite.
Castle ActiveRecord — проект, реализующий паттерн ActiveRecord. Castle ActiveRecord основан на NHibernate, но его отображение, основанное на атрибутах, освобождает разработчика от написания XML-описаний сущностей и связей, которые необходимы при использовании NHibernate напрямую [10].
Doctrine — объектно-реляционный проектор (ORM) для PHP 7.1+, который базируется на слое абстракции доступа к БД (DBAL). Одной из ключевых возможностей Doctrine является запись запросов к БД на собственном объектно-ориентированном диалекте SQL, называемом DQL (Doctrine Query Language) и базирующемся на идеях HQL (Hibernate Query Language) [11].
Django — свободный фреймворк для веб-приложений на языке Python, использующий шаблон проектирования MVC. Для работы с базой данных Django использует собственный ORM, в котором модель данных описывается классами Python, и по ней генерируется схема базы данных [12].
В таблице 1 представлен сравнительный анализ некоторых программных решений, которые реализуют объектно-реляционное отображение (ORM).
Таблица 1
Анализ существующих программных решений
|
Параметры |
|||
Программные решения |
Язык |
Opensource |
Лицензия |
Поддерживаемые БД |
ODB [13] |
C++ |
+ |
GNU GP |
SQLite, MySQL, Oracle и др. |
EclipseLink |
Java |
+ |
Eclipse Public License |
MySQL, Oracle, PostgreSQL и др. |
Hibernate |
Java |
+ |
GNU LGP |
SQLite, MySQL, Oracle и др. |
Nhibernate |
C# |
+ |
GNU LGP |
SQLite, MySQL, Oracle и др. |
Castle ActiveRecord |
C# |
+ |
GNU LGP |
SQLite, MySQL, Oracle и др. |
Doctrine |
PHP |
+ |
MIT |
SQLite, MySQL, Oracle и др. |
EntityDAC [14] |
Delphy |
- |
Singe/Team/Site License |
SQLite, MySQL, Oracle и др. |
«+» — присутствие функционала
«-» — отсутствие функционала
Литература:
- ORM // Википедия. URL: https://ru.wikipedia.org/wiki/ORM.
- Сэнди Метц. Ruby. Объектно-ориентированное проектирование. — ИД «ПИТЕР», 2017. — 304 с.
- Hibernate. What is Object/Relational Mapping? // HIBERNATE. URL: http://hibernate.org/orm/what-is-an-orm.
- Фримен Эр., Фримен Эл., Бейтс Б., Сьерра К. Паттерны проектирования. — Питер, 2011. — 656 c.
- ActiveRecord // Википедия. URL: https://ru.wikipedia.org/wiki/ActiveRecord.
- Persistence SQL or NOT // EclipseLink. URL: http://www.eclipse.org/eclipselink/#abou.
- James Elliott. Hibernate: A Developer's Notebook. — O'Reilly Media, 2009. — 192 с.
- Introduction to Entity Framework // Microsoft. URL: https://msdn.microsoft.com/en-us/library/aa937723(v=vs.113).aspx.
- Documentation // NHibernate. The object-relational mapper for.NET. URL: http://nhibernate.info/doc/index.html.
- Castle ActiveRecord Documentation // github. castleproject/ActiveRecord. URL: https://github.com/castleproject/ActiveRecord/blob/master/docs/README.md.
- Jonathan H. Wage, Roman Borschel, Guilherme Blanco. Doctrine Orm for PHP (1.2). — A Sensio Labs book, 2010. — 552 с.
- Django documentation // django. URL: https://docs.djangoproject.com/en/2.0.
- ODB: C++ Object-Relational Mapping (ORM) // CODESYNTHESIS. URL: https://www.codesynthesis.com/products/odb.
- EntityDAC — ORM for Delphi with LINQ support // Devart. URL: https://www.devart.com/entitydac/.