Думаю, впервые я услышал об ORM 10 лет назад. Я обнаружил эту технику в учебнике NetBeans, в котором объяснялось, как создавать классы Java из базы данных MySQL. Я провел несколько тестов, и все прошло хорошо. Мне очень понравились концепции, но не исполнение. Я был очень разочарован этапом генерации, потому что мне всегда приходилось регенерировать классы для каждого обновления структуры базы данных. На самом деле эта проблема была связана с языком, используемым для сопоставления, которое необходимо скомпилировать. Я сказал себе, что было бы проще использовать динамический язык, который мог бы генерировать эти классы во время выполнения. Вот почему в то время я начал создавать свою собственную ORM с помощью JavaScript. Это сработало довольно хорошо, но я застрял с большим ограничением: MySQL. Реляционная структура таблиц не соответствовала собственным объектам JavaScript. Так что составление карты оказалось не таким простым, как я хотел.

Но через несколько лет все изменилось, когда базы данных NoSQL становились все более популярными. Мы могли использовать чистые объекты JSON в качестве документов, и мы могли управлять данными NoSQL как собственными объектами JavaScript.

В этом посте я покажу вам, как теперь легко создать ODM (Object-Document Mapping) с помощью JavaScript.

Мой первый ODM

Начнем с выбора базы данных NoSQL. Мы воспользуемся моей любимой, я называю ее универсальной базой данных: {}.

Он легкий, может работать как на сервере, так и в браузере. Все нравится!

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

Но мы также можем передать один объект в качестве параметра:

Вы заметили, что этот параметр похож на документ? Это основная идея ODM: использовать документ как параметр конструктора класса.

Имея это в виду, давайте создадим класс, который будет управлять сопоставлением между документами и экземплярами классов:

В этом классе мы сделали несколько вещей:

  • мы получаем имя коллекции в базе данных: в нашем случае имя класса,
  • мы генерируем уникальный id для документа,
  • добавляем документ в базу и
  • мы создаем методы получения и установки для каждого свойства экземпляра, который будет управлять связанным документом в базе данных.

Теперь давайте проведем с ним несколько тестов:

Теперь у нас есть полная синхронизация между документами и экземплярами. И мы сделали это всего с 30 строками кода!

Вывоз документов

Отпусти дальше. И если хотите экспортировать документы? Сделать это очень просто:

В нашем случае мы предполагаем, что все документы действительны в формате JSON, поэтому мы можем экспортировать их с помощью собственного JavaScript API.

Теперь давайте проведем с ним несколько тестов:

В этом примере мы экспортируем все документы, созданные для определенного класса. Это означает, что теперь мы можем сериализовать все объекты в строку. Довольно круто, правда?

Ввоз документов

Теперь сделаем что-нибудь посложнее с импортом документов. Когда мы импортируем документы в определенную коллекцию, мы хотим создать связанные с ними объекты:

Теперь давайте немного обновим для этой цели основной класс:

Отличие от предыдущего класса в том, что теперь мы добавляем созданный экземпляр в список instance.

Давайте проверим это:

Теперь мы можем десериализовать данные в объекты. Кроме того, мы также можем знать точное количество созданных объектов в любой момент, это количество объектов в моем списке экземпляров.

Управление отношениями данных

А как насчет отношений? В мире NoSQL мы можем моделировать отношения, используя id документа в качестве значения свойства для создания ссылки. Если мы будем следовать этому шаблону, управление отношениями станет очень простым:

Чтобы отличить значение от ссылки, мы добавляем это новое правило: если значение начинается с @, это означает, что оно представляет id документа.

Давайте теперь создадим связь между объектами:

Теперь давайте сделаем эту ссылку на уровне API:

Как видите, с помощью ODM мы можем очень легко создать отношения один-к-одному.

Заключение

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

Если вы задумаетесь, то поймете, что на самом деле ODM - это способ управления хранилищем вашего приложения. Каждый вид компонентов имеет собственное хранилище (т.е. коллекцию в базе данных), и ими можно управлять, как в Redux. Но здесь вы находитесь на функциональном уровне (вы управляете функциональными объектами), а не на техническом уровне (где вы управляете данными).

Я сделал несколько примеров CodePen, чтобы вы могли прямо сейчас начать играть с ODM:

Если вы хотите углубиться, вы можете взглянуть на System Runtime, библиотеку JavaScript, которую я создал, которая применяет все шаблоны, о которых я говорил в этом посте.