Выпущена новая основная версия TypeScript ORM, ознакомьтесь с ее новыми функциями и критическими изменениями.
Если вы не знаете…
Если вы никогда не слышали о MikroORM, это ORM-преобразователь данных TypeScript с Unit of Work и Identity Map. В настоящее время он поддерживает драйверы MongoDB, MySQL, PostgreSQL и SQLite. Ключевые особенности ORM:
Вы можете прочитать полную вводную статью здесь или просмотреть документацию.
Встроенный Knex.js
Вы, вероятно, уже знаете Knex.js, но если вы этого не сделаете, это построитель SQL-запросов с батарейками для Postgres, MSSQL, MySQL , MariaDB, SQLite3, Oracle и Amazon Redshift, обеспечивающие гибкость, переносимость и удобство использования использовать.
Knex.js теперь используется как конструктор запросов и как средство выполнения запросов для всех драйверов SQL. Это позволяет упростить реализацию драйверов SQL, а также открывает некоторые новые возможности.
Использование Knex.js
Вы можете получить доступ к сконфигурированному экземпляру knex
с помощью метода qb.getKnexQuery()
. Затем вы можете выполнить его с помощью Connection.execute()
и сопоставить результаты с помощью EntityManager.map()
.
Вы также можете получить чистый и настроенный экземпляр knex из соединения с помощью метода getKnex()
. Поскольку этот метод недоступен в базовом классе Connection
, вам нужно будет либо вручную ввести приведение соединения к AbstractSqlConnection
(или фактическую реализацию, которую вы используете, например MySqlConnection
), либо предоставить правильный тип драйвера для вашего экземпляра EntityManager
, который будет затем автоматически выводится в em.getConnection()
методе.
Реализации драйверов и соединений не экспортируются напрямую из модуля
mikro-orm
. Вы можете импортировать их изmikro-orm/dist
(например,import { PostgreSqlDriver } from 'mikro-orm/dist/drivers/PostgreSqlDriver'
).
Пул соединений
Благодаря тому, что Knex.js используется в качестве обработчика запросов, наконец-то стала доступна поддержка пула соединений. Tarn.js используется для этого внутри, используя пул соединений с min: 2, max: 10
для библиотек MySQL и PG и одно соединение для sqlite3 по умолчанию. Используйте параметр pool
, чтобы изменить это при инициализации ORM.
Еще драйверы SQL?
Одной из самых веских причин для интеграции Knex.js было то, что он позволяет упростить и унифицировать драйверы SQL и открывает двери для внедрения новых драйверов SQL. Knex.js в настоящее время поддерживает (кроме тех, которые в настоящее время поддерживаются MikroORM): MSSQL, Oracle и Amazon Redshift.
Благодаря классам AbstractSqlDriver
и AbstractSqlConnection
их должно быть довольно просто реализовать. Я открыт для PR для этих драйверов, так как я хотел бы сосредоточиться в основном на разработке новых функций ORM вместо изучения новых диалектов SQL, которые я никогда не использовал. Я буду рад помочь всем, кто заинтересован - не стесняйтесь обращаться ко мне через Slack, электронную почту или GitHub.
Упрощенное определение сущности
Теперь больше не нужно объединять сущности с IEntity
интерфейсом, который загрязнял интерфейс сущности внутренними методами. Введены новые интерфейсы IdentifiedEntity<T>
, UuidEntity<T>
и MongoEntity<T>
, которые должны быть реализованы сущностями. Они не добавляют никаких новых свойств или методов, поддерживая чистоту интерфейса объекта.
Интерфейс IEntity
был переименован в AnyEntity<T, PK>
, и у него больше нет общедоступных методов, таких как toJSON()
, toObject()
или init()
. Можно использовать метод wrap()
, предоставленный ORM, который при необходимости улучшит тип свойства с помощью этих методов (например, await wrap(book.author).init()
). Чтобы все методы были доступны для объекта, вы все равно можете использовать слияние интерфейсов с WrappedEntity<T, PK>
, которое расширяет AnyEntity<T, PK>
и определяет все эти методы.
Вам нужно будет пометить объект, реализовав один из *Entity
интерфейсов:
IdEntity<T>
для числового / строкового PK в свойствеid
(id: number
)UuidEntity<T>
для строки PK на свойствеuuid
(uuid: string
)MongoEntity<T>
для монго, гдеid: string
и_id: ObjectId
обязательныAnyEntity<T, PK>
для других возможных свойств (введите имя свойства PK в параметрPK
, например:AnyEntity<Book, 'myPrimaryProperty'>'
)
Чтобы сохранить все общедоступные методы, которые были частью интерфейса IEntity
в v2, вы можете использовать WrappedEntity<T, PK>
через слияние интерфейсов.
Вложенные запросы
Драйвер SQL теперь поддерживает вложенные where
и orderBy
условия. Это означает, что вы можете запрашивать свойства отношения, и отношение будет автоматически соединено для вас. Они доступны как в EntityManager
, так и в QueryBuilder
API.
Строгий набор запросов
Раньше параметр where методов поиска EntityManager
(find()
, findOne()
, count()
) был слабо типизирован. Это позволяло пользователям передавать туда практически все, что угодно.
Теперь запрос строго типизирован, можно использовать только свойства сущности и операторы, а также проверяется тип значения свойства.
Улучшенный генератор схем
SchemaGenerator
теперь поддерживает создание, обновление и удаление схемы. Вы можете получить SQL-запросы в виде массива строк или напрямую запустить их в базе данных.
Всегда сначала проверяйте сгенерированный SQL перед его запуском.
Также имеется новый атрибут свойства columnType
, который можно использовать для явного указания типа столбца для конкретной базы данных.
Миграции
Лучшим способом обработки обновлений схемы, чем использование SchemaGenerator
напрямую, является использование миграции. MikroORM 3 имеет интегрированную поддержку миграций через умзуг. Это позволяет вам создавать миграции с текущими различиями в схемах.
По умолчанию каждая миграция будет выполняться внутри транзакции, и все они будут заключены в одну главную транзакцию, поэтому, если одна из них не удастся, все будет откатано.
Создание сущностей из текущей базы данных
В качестве аналога SchemaGenerator
, распространяющего изменения в ваших сущностях на схему базы данных, теперь есть EntityGenerator
, который поможет вам с обратным проектированием текущей схемы базы данных и созданием сущностей на ее основе.
Он поддерживает базовое определение сущности, включая отношения ManyToOne и OneToOne. В настоящее время ManyToMany будет сгенерирован как дополнительная сущность с двумя отношениями ManyToOne, и вам нужно будет провести рефакторинг самостоятельно.
Хотя это может очень помочь, есть много возможностей для улучшения. В будущем я хотел бы реализовать правильную поддержку отношений ManyToMany, а также для перечислений и индексов. Еще одно возможное расширение - это возможность редактировать существующие объекты (синхронизировать их с текущей схемой).
CLI
Хотя вы можете использовать SchemaGenerator
и EntityGenerator
вручную, гораздо проще использовать новый инструмент CLI. Просто создайте файл конфигурации в корневом каталоге или добавьте его путь к package.json. Файлы TypeScript также поддерживаются через ts-node
:
Теперь вы можете использовать CLI с помощью npx
:
Чтобы проверить свою настройку, вы можете использовать команду mikro-orm debug
. После того, как вы правильно настроили его, вы также можете повторно использовать его при инициализации ORM:
// when no options parameter is provided, CLI config will be used const orm = await MikroORM.init();
Пользовательские типы сопоставления
С помощью Custom Types мы теперь можем улучшить то, как значение базы данных будет представлено в ORM. Вы можете определить собственные типы, расширив абстрактный класс Type
, у него есть 4 дополнительных метода:
convertToDatabaseValue(value: any, platform: Platform): any
Преобразует значение из его JS-представления в его представление в базе данных этого типа. По умолчанию возвращает без изменений value
.
convertToJSValue(value: any, platform: Platform): any
Преобразует значение из его представления в базе данных в его JS-представление этого типа. По умолчанию возвращает без изменений value
.
toJSON(value: any, platform: Platform): any
Преобразует значение из его JS-представления в его сериализованную форму JSON этого типа. По умолчанию преобразуется в значение базы данных.
getColumnType(prop: EntityProperty, platform: Platform): string
Получает фрагмент объявления SQL для поля этого типа. По умолчанию возвращает columnType
данного свойства.
Вот упрощенная версия DateType
, которая уже присутствует в ORM:
И многое другое…
Есть еще много новых функций, см. Журнал изменений, чтобы прочитать полный список. Вот некоторые из них, о которых стоит упомянуть:
- Улучшенная поддержка ссылок
- Поддержка Navite Enum
em.findAndCount()
иem.findOneOrFail()
методыReflectMetadataProvider
как быстрая альтернатива отражению ts-morph- Улучшено ведение журнала с выделением запроса
- Поддержка комплектации через Webpack
- Нетерпеливая загрузка
- Прочитать связи
- Более строгая проверка определения сущности
Заметные критические изменения
Вот краткий список критических изменений. Вы можете увидеть полный список в документации: https://mikro-orm.io/docs/upgrading-v2-to-v3/.
Автоматическая очистка отключена по умолчанию
Если раньше в вашей конфигурации ORM было
autoFlush: false
, теперь вы можете удалить эту строку, никаких изменений в вашем приложении не требуется.
Значение по умолчанию для autoFlush
теперь false
. Это означает, что вам нужно вызвать em.flush()
себя, чтобы сохранить изменения в базе данных. Вы все равно можете изменить это с помощью опций ORM, чтобы упростить переход, но обычно это не рекомендуется, так как это может вызвать нежелательные небольшие транзакции, создаваемые вокруг каждого persist
.
API транзакций
Транзакции теперь требуют использования em.transactional()
метода, предыдущие методы _82 _ / _ 83 _ / _ 84_ теперь удалены.
Сделаем его немного более профессиональным…
Ничего особенного, но, вероятно, стоит упомянуть - репозиторий MikroORM был перенесен в новую MikroORM GitHub Organization, а сайт теперь перемещен в mikro-orm.io. Старые ссылки должны быть правильно перенаправлены, если вы найдете 404, сообщите мне о проблемах с GitHub!
Веб-сайт также был переработан - теперь он построен на Docusaurus (v2) и обеспечивает полнотекстовый поиск с помощью Algolia. Документы теперь тоже версированы.
Что дальше?
Вот некоторые функции, над которыми я планирую работать в ближайшем будущем:
- Составные первичные ключи
- Транзакции в MongoDB
- Комплексная гидратация объединенных наборов результатов
- Журнал медленных запросов
- Поддержка M: N в генераторе сущностей
Есть еще несколько интересных предложений в вопросах Github, например, Dataloader integration.
WDYT?
Итак, это MikroORM 3, что вы о нем думаете? Какие функции или изменения вы хотели бы увидеть дальше? Или какую часть документации нужно улучшить и как?
Нравится МикроОРМ? ⭐️ Пометьте на GitHub и поделитесь этой статьей со своими друзьями.