Думаю, впервые я услышал об 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, которую я создал, которая применяет все шаблоны, о которых я говорил в этом посте.