拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

MikroORM 自定义数据库驱动开发指南:从 Platform 到 Driver 的四层架构与完整实现

MikroORM 自定义数据库驱动开发指南:从 Platform 到 Driver 的四层架构与完整实现 后端【免费下载链接】mikro-ormTypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, MariaDB, MS SQL Server, PostgreSQL and SQLite/libSQL databases.项目地址https://gitcode.com/gh_mirrors/mi/mikro-orm点击查看免费下载本文以 MikroORM 6.x 官方文档 custom-driver.md 为核心骨架讲解如何为 MikroORM 接入一个官方尚未支持的数据库。你将掌握驱动架构中 Platform、SchemaHelper、Connection、Driver 四个核心类的职责与实现要点并学会结合mikro-orm/sql的抽象基类快速搭建 SQL 驱动以及直接继承核心基类实现非 SQL 驱动的完整路径。驱动架构总览四个类各司其职MikroORM 的驱动层被刻意拆分为多个关注点单一的类任何一个数据库的接入都需要或可以实现以下四个部分类职责核心位置Platform描述目标数据库的能力与特性事务、命名策略、主键规范化、标识符引用等packages/core/src/platforms/Platform.tsSchemaHelper提供建表/改表等 schema 相关 SQL 片段的生成方式是 Platform 的一部分mikro-orm/core的SchemaHelperConnection负责与数据库建立连接并执行查询packages/core/src/connections/Connection.tsDriver编排 Connection 与 Platform把实体操作find、insert、update、delete、count 等持久化到数据库packages/core/src/drivers/DatabaseDriver.ts这套分层设计与 MikroORM 的 Data Mapper、Unit of Work、Identity Map 模式一脉相承EntityManager 只与IDatabaseDriver接口打交道而驱动内部如何连接数据库、如何生成 SQL、如何处理方言差异全部封装在这四个类中。因此只要实现这四个类MikroORM 的实体定义、关系映射、事务、级联、Identity Map 等上层能力即可原样复用。Platform定义数据库的能力边界Platform是驱动能力的说明书MikroORM 通过它判断某个数据库支持哪些特性。从源码看Platform.ts 是一个抽象基类绝大多数方法都有默认实现默认返回false或保守值你需要按目标数据库的真实能力覆盖import { Platform } from mikro-orm/core; export class MyCustomPlatform extends Platform { protected abstract schemaHelper: MyCustomSchemaHelper; // 在这里覆盖默认设置 usesPivotTable(): boolean; supportsTransactions(): boolean; supportsSavePoints(): boolean; getNamingStrategy(): { new (): NamingStrategy; }; getIdentifierQuoteCharacter(): string; getParameterPlaceholder(index?: number): string; usesReturningStatement(): boolean; normalizePrimaryKeyT number | string(data: IPrimaryKey): T; denormalizePrimaryKey(data: IPrimaryKey): IPrimaryKey; getSerializedPrimaryKeyField(field: string): string; }各方法含义与默认行为如下usesPivotTable()M:N 关系是否使用中间表。SQL 驱动返回trueMongoDB 这类文档数据库返回false源码默认即false。supportsTransactions()是否支持事务。默认值受全局配置disableTransactions影响见 Platform.ts若目标数据库不支持事务可固定返回false。supportsSavePoints()是否支持保存点嵌套事务。getNamingStrategy()返回默认命名策略构造器基类默认返回UnderscoreNamingStrategy。getIdentifierQuoteCharacter()标识符引用字符如 PostgreSQL 用双引号。getParameterPlaceholder(index?)SQL 参数占位符如?或$1。usesReturningStatement()是否支持INSERT ... RETURNING子句如 PostgreSQL 支持、MySQL 不支持默认false。normalizePrimaryKey()/denormalizePrimaryKey()主键在数据库原始形态与 ORM 内部形态之间的双向转换例如把 MongoDB 的ObjectId归一化为字符串。getSerializedPrimaryKeyField(field)序列化时主键字段的展示名称。除上述方法外Platform.ts 还提供了一系列特性开关包括usesOutputStatement()MSSQL 的 OUTPUT 子句、supportsNativeEnums()PostgreSQL 原生枚举、usesEnumCheckConstraints()、supportsMaterializedViews()、supportsPartitionedTables()声明式表分区、indexForeignKeys()是否自动为外键建索引等均可在自定义 Platform 中按需覆盖。SchemaHelper驱动 schema 生成逻辑SchemaHelper是 Platform 的组成部分负责提供如何构建 schema的信息——即 MikroORM 的 SchemaGenerator 在生成建表、改表 SQL 时所需的各种 SQL 片段import { SchemaHelper } from mikro-orm/core; export class MyCustomSchemaHelper extends SchemaHelper { // 在这里覆盖默认设置 getIdentifierQuoteCharacter(): string; getSchemaBeginning(): string; getSchemaEnd(): string; getSchemaTableEnd(): string; getAutoIncrementStatement(meta: EntityMetadata): string; getPrimaryKeySubtype(meta: EntityMetadata): string; getTypeDefinition(prop: EntityProperty, types?: Recordstring, string, lengths?: Recordstring, number): string; getUnsignedSuffix(prop: EntityProperty): string; supportsSchemaConstraints(): boolean; supportsSchemaMultiAlter(): boolean; supportsSequences(): boolean; quoteIdentifier(field: string): string; dropTable(meta: EntityMetadata): string; indexForeignKeys(): boolean; }关键方法的职责getTypeDefinition()把实体属性的 TypeScript/ORM 类型翻译成目标数据库的列类型定义是 schema 生成最核心的方法之一。getAutoIncrementStatement()返回自增主键AUTO_INCREMENT / IDENTITY / SERIAL的 SQL 片段。supportsSequences()是否支持序列如 PostgreSQL、Oracle。supportsSchemaConstraints()/supportsSchemaMultiAlter()schema 约束能力与多条 ALTER 语句的合并能力。quoteIdentifier()标识符引用封装。dropTable()生成 DROP TABLE 语句。需要 schema 生成能力时可参照现有驱动的 SchemaHelper 实现例如PostgreSqlSchemaHelper、MySqlSchemaHelper位于对应驱动包的schema目录下来编写你自己的版本。Connection负责与数据库通信第三个部分是连接包装器负责真正与数据库通信。继承核心的Connection抽象类需要实现以下抽象方法签名与源码一致见 Connection.tsimport { Connection } from mikro-orm/core; export class MyCustomConnection extends Connection { // 实现抽象方法 connect(): Promisevoid; isConnected(): Promiseboolean; close(force?: boolean): Promisevoid; getDefaultClientUrl(): string; execute(query: string, params?: any[], method?: all | get | run): PromiseQueryResult | any | any[]; }从源码看Connection基类还提供了checkConnection()、ensureConnection()、executeDump()、getNativeClient()等方法作为可选能力默认抛出不支持错误自定义连接可以按需覆盖。例如checkConnection()返回{ ok: true }或{ ok: false; reason: string; error?: Error }用于连接健康检查getNativeClient()用于向用户暴露底层原生客户端如pg的连接池。Driver把实体操作持久化到数据库最后一部分是Driver它负责使用 Connection 与 Platform 将实体变更持久化到数据库。官方文档给出了两条实现路线SQL 驱动优先继承AbstractSqlDriver来自mikro-orm/sql可以复用完整的 SQL 查询构建器、连接策略、批量操作等能力非 SQL 驱动继承核心的DatabaseDriver抽象类位于 packages/core/src/drivers/DatabaseDriver.ts自行实现查询语义绝对控制直接实现IDatabaseDriver接口定义于 packages/core/src/drivers/IDatabaseDriver.ts接口包含find、findOne、findVirtual、stream、nativeInsert、nativeInsertMany、nativeUpdate、nativeDelete、count、createEntityManager、connect、close、reconnect、getConnection等完整契约。继承DatabaseDriver的最小实现如下抽象方法签名与 DatabaseDriver.ts 一致import { DatabaseDriver } from mikro-orm/core; export class MyCustomDriver extends DatabaseDriver { // 初始化连接与平台 protected readonly connection new MyCustomConnection(this.config); protected readonly platform new MyCustomPlatform; // 并实现抽象方法 findT extends AnyEntity(entityName: string, where: FilterQueryT, populate?: string[], orderBy?: Recordstring, QueryOrder, limit?: number, offset?: number): PromiseT[]; findOneT extends AnyEntity(entityName: string, where: FilterQueryT | string, populate: string[]): PromiseT | null; nativeInsertT extends AnyEntityTypeT(entityName: string, data: EntityDataT): PromiseQueryResult; nativeUpdateT extends AnyEntity(entityName: string, where: FilterQueryT | IPrimaryKey, data: EntityDataT): PromiseQueryResult; nativeDeleteT extends AnyEntity(entityName: string, where: FilterQueryT | IPrimaryKey): PromiseQueryResult; countT extends AnyEntity(entityName: string, where: FilterQueryT): Promisenumber; }需要注意DatabaseDriver的构造函数签名是(config: Configuration, dependencies: string[])第二个参数是驱动依赖的 npm 包名列表MikroORM 启动时会据此校验依赖是否安装并给出友好报错详见 DatabaseDriver.ts。此外基类还提供了若干可选方法如nativeUpdateMany、nativeClone、findVirtual、countVirtual、stream等默认实现会抛出当前驱动不支持的错误需要时再覆盖。基于 mikro-orm/sql 快速搭建 SQL 驱动大多数自定义驱动面向的是 SQL 数据库。此时强烈建议继承mikro-orm/sql包中的抽象基类——SQL 层内部基于 Kysely 构建查询连接类只需提供一个 Kysely dialect 即可复用绝大部分能力。从源码看AbstractSqlConnection.ts 中声明了抽象方法createKyselyDialect(overrides: Dictionary)连接生命周期、事务、保存点、查询执行与流式读取均由基类通过 Kysely 统一处理。Connection提供 Kysely dialectimport { AbstractSqlConnection } from mikro-orm/sql; import type { Dialect, Dictionary } from kysely; export class MyConnection extends AbstractSqlConnection { createKyselyDialect(overrides: Dictionary): Dialect { // 返回目标数据库的 Kysely dialect // overrides 中包含来自 MikroORM 配置的 driverOptions return new MyKyselyDialect({ ... }); } }Platform描述 SQL 数据库特性继承AbstractSqlPlatform它已继承核心Platform并提供合理的 SQL 默认值按需覆盖能力方法import { AbstractSqlPlatform } from mikro-orm/sql; export class MyPlatform extends AbstractSqlPlatform { // 覆盖方法以描述数据库能力例如 supportsTransactions(): boolean { return true; } usesReturningStatement(): boolean { return false; } getDefaultSchemaName(): string | undefined { return undefined; } }AbstractSqlPlatform之上常见的可覆盖方法及用途方法用途supportsTransactions()数据库是否支持事务usesReturningStatement()是否支持INSERT ... RETURNINGsupportsSchemas()是否支持命名 schema如 PostgreSQLgetDefaultSchemaName()支持 schema 时的默认 schema 名quoteIdentifier(id)标识符引用方式默认id双引号quoteValue(value)字面量值的引用方式getCurrentTimestampSQL(length)当前时间戳的 SQL 表达式getSearchJsonPropertySQL(path, type, aliased)JSON 属性访问语法escape(value)SQL 字面量转义若需要 schema 生成支持同样可以提供一个自定义SchemaHelper参考现有驱动如PostgreSqlSchemaHelper、MySqlSchemaHelper。Driver串联一切并声明原生依赖import { type Configuration, EntityManagerType } from mikro-orm/core; import { AbstractSqlDriver } from mikro-orm/sql; import { MyConnection } from ./MyConnection.js; import { MyPlatform } from ./MyPlatform.js; export class MyDriver extends AbstractSqlDriverMyConnection { constructor(config: Configuration) { super(config, new MyPlatform(), MyConnection, [kysely, my-native-driver]); } }super()的最后一个参数是必须安装的 npm 包名数组——MikroORM 启动时会检查这些依赖缺失时给出友好的错误提示。AbstractSqlDriver承担了全部重活find、findOne、nativeInsert、nativeUpdate、nativeDelete、count、查询构建、joined 加载策略等。使用自定义驱动通过driver配置项把驱动类交给 MikroORMconst orm await MikroORM.init({ driver: MyDriver, dbName: my-database, entities: [Author, Book], });非 SQL 驱动实现要点对于文档型、键值型等非 SQL 数据库没有查询构建器可以依赖需要直接继承核心基类并实现更多方法Connection继承Connection实现connect()、isConnected()、checkConnection()、close(force?)并自行添加目标数据库特有的查询方法Platform继承Platform并覆盖特性开关例如usesPivotTable(): false、supportsTransactions(): false、自定义getNamingStrategy()、normalizePrimaryKey()与denormalizePrimaryKey()等Driver继承DatabaseDriverMyConnection在构造器中实例化connection与platform并实现find、findOne、nativeInsert、nativeInsertMany、nativeUpdate、nativeDelete、count等 CRUD 抽象方法。仓库中的 MongoDB 驱动是完整的非 SQL 驱动参考实现其源码位于 packages/mongodb/src包含MongoConnection.ts、MongoDriver.ts、MongoPlatform.ts、MongoExceptionConverter.ts、MongoSchemaGenerator.ts等文件展示了连接、平台、驱动、异常转换、schema 生成的全套做法是学习自定义非 SQL 驱动的最佳范例。参考实现从现有驱动包学习仓库中已内置多个生产级驱动可作为自定义驱动的直接参考PostgreSQLmikro-orm/postgresql功能最完整的 SQL 驱动含 schema 支持、JSON 操作符、数组类型等MySQLmikro-orm/mysql带 MySQL 特定平台特性的 SQL 驱动SQLitemikro-orm/sqlite极简 SQL 驱动是入门自定义 SQL 驱动的良好起点MongoDBmikro-orm/mongodb直接继承DatabaseDriver的非 SQL 驱动范本。所有驱动包均位于仓库的 packages 目录下。编写自定义驱动时建议先对照这些现有实现理解四个类的分工再按先 Connection 后 Platform、最后 Driver的顺序逐步补齐并用真实的实体读写测试验证每条路径。赞分享后端【免费下载链接】mikro-ormTypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, MariaDB, MS SQL Server, PostgreSQL and SQLite/libSQL databases.项目地址https://gitcode.com/gh_mirrors/mi/mikro-orm点击查看免费下载相关推荐MikroORM 自定义数据库驱动开发指南基于 Platform/Connection/Driver 三层架构扩展 SQL 与非 SQL 数据库MikroORM 自定义数据库驱动开发指南基于 Platform/Connection/Driver 三层架构扩展 SQL 与非 SQL 数据库 如果你希望让后端深入剖析 MikroORM 自定义 Driver 开发从 Platform、Connection 到 Driver 的三层架构与实战实现深入剖析 MikroORM 自定义 Driver 开发从 Platform、Connection 到 Driver 的三层架构与实战实现 导读 MikroO后端MikroORM 自定义驱动Custom Driver开发指南基于 Platform、SchemaHelper、Connection、Driver 四大组件实现全新数据库支持MikroORM 自定义驱动Custom Driver开发指南基于 Platform、SchemaHelper、Connection、Driver 四大组后端上一篇Xbox成就解锁器5个核心技术突破让游戏成就管理变得简单高效下一篇微信数据库解密终极指南3步掌握AES-256加密数据恢复创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表