ARTICLE DETAIL

资讯详情

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

MikroORM SQL 驱动完整使用指南:安装、QueryBuilder、事务与原生 SQL 操作(v7)

MikroORM SQL 驱动完整使用指南:安装、QueryBuilder、事务与原生 SQL 操作(v7) 后端【免费下载链接】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 以 Data Mapper、Unit of Work 与 Identity Map 三大模式为核心是一套面向 Node.js/TypeScript 的现代 ORM内置对 MySQL、MariaDB、PostgreSQL、CockroachDB、SQLite、libSQL/Turso、MSSQL 与 Oracle 等 SQL 数据库的一流支持。本文以 v7 文档 usage-with-sql.md 为骨架系统讲解如何为不同 SQL 数据库安装对应驱动包、引导MikroORM.init、通过QueryBuilder执行原生 SQL、管理事务、使用原生集合方法并梳理各数据库平台的已知限制。读完本文你将能够针对任意 SQL 数据库快速搭建 MikroORM 环境并在ORM 托管与原生 SQL两条路径之间自如切换。一、安装对应数据库的驱动包MikroORM 采用核心 驱动的分包架构mikro-orm/core提供 ORM 本体实体、EntityManager、Unit of Work、Identity Map各数据库驱动包负责连接、方言与平台差异。官方推荐直接安装与你所用数据库对应的驱动包# for mysql同样适用于 mariadb npm install mikro-orm/core mikro-orm/mysql # for mariadb同样适用于 mysql npm install mikro-orm/core mikro-orm/mariadb # for postgresql同样适用于 cockroachdb npm install mikro-orm/core mikro-orm/postgresql # for sqlite npm install mikro-orm/core mikro-orm/sqlite # for libsql/turso npm install mikro-orm/core mikro-orm/libsql # for mssql npm install mikro-orm/core mikro-orm/mssql # for oracle npm install mikro-orm/core mikro-orm/oracledb需要说明的是MySQL 与 MariaDB、PostgreSQL 与 CockroachDB 之间驱动可互相通用——MariaDB 协议兼容 MySQLCockroachDB 兼容 PostgreSQL 方言。仓库中还额外提供了mikro-orm/sql-jsSQLite 的 WASM 实现、mikro-orm/pglitePostgreSQL 的嵌入式 WASM 实现以及面向 Bun/边缘环境的mikro-orm/libsql等驱动包全部位于 packages/ 目录下例如 packages/mysql/package.json、packages/postgresql/package.json。SQLite 有专门的扩展配置如自定义扩展、Turso、Cloudflare D1、自定义驱动详见 SQLite 使用指南。若使用的是 libsql/Turso也可参考 libsql 包 的实现与 tests/features/libsql/libsql.test.ts。二、通过MikroORM.init引导应用安装驱动包后只需调用一次MikroORM.init即可完成引导。初始化完成后orm.em属性即暴露了可直接使用的EntityManagerimport { MikroORM } from mikro-orm/postgresql; // 或任意其他 SQL 驱动包 const orm await MikroORM.init({ entities: [./dist/entities], // 指向你的 JS 实体编译产物 dist相对 baseDir 解析 dbName: my-db-name, }); console.log(orm.em); // 通过 em 属性访问 EntityManager这里有一个值得注意的类型细节为了访问驱动特有的方法如em.createQueryBuilder()、em.getDriver()等必须从驱动包而非mikro-orm/core导入MikroORM/EntityManager/EntityRepository类。如果已经用 core 包初始化了orm也可以把orm.em强转为驱动包导出的EntityManager类型import { EntityManager } from mikro-orm/postgresql; const em orm.em as EntityManager; const qb em.createQueryBuilder(...);从源码结构看这套类型体系是这样组织的驱动包内的MikroORM类如 PostgreSqlMikroORM继承自 core并覆写了em的类型为驱动专属的SqlEntityManager/PostgreSqlEntityManagerSQL 驱动共同的实体管理器基类是 SqlEntityManager所有 SQL 方言的QueryBuilder工厂方法即由此注入。同理SqlEntityRepository 提供了仓库层级的原生查询入口。三、自定义驱动接入未内置支持的数据库如果目标数据库不在官方支持列表内MikroORM 允许你实现自己的驱动类。创建自定义驱动的完整指引见 自定义驱动指南然后通过driver配置项把驱动类交给 ORMimport { MyCustomDriver } from ./MyCustomDriver.ts; const orm await MikroORM.init({ entities: [Author, Book, ...], dbName: my-db-name, driver: MyCustomDriver, // 传入驱动类本身而不是类的名称字符串 });从实现看驱动类需要继承 AbstractSqlDriverSQL 系或 core 的DatabaseDriverNoSQL 系并提供对应的Connection与PlatformAbstractSqlDriver的构造签名正是(config, platform, connection, connector)三元组例如 PostgreSqlDriver 就是这么组合出来的。四、Schema 维护与 SchemaGeneratorSQL 数据库的 Schema表结构、约束、索引不会由 ORM 在运行时自动创建。当前策略是由你负责维护数据库 Schema首次建表时可以使用SchemaGenerator辅助工具生成初始 DDL。SchemaGenerator既可以通过 CLI 使用npx mikro-orm schema:create等命令见 CLI 包也可以在代码中直接调用。仓库中SchemaGenerator的实现位于 SqlSchemaGenerator它与 DatabaseSchema、SchemaComparator 配合可以完成createSchema、updateSchema、dropSchema、ensureDatabase等操作Schema 差异对比逻辑集中在 SchemaHelper。更多用法包括生成 SQL 文件、对比线上差异、多 Schema 场景可参考 SchemaGenerator 文档 以及 tests/features/schema-generator/ 下的系列测试。五、ManyToMany 关系与中间表Pivot Table与MongoDriver直接用数组存关联对象不同SQL 数据库中的ManyToMany关系通过**中间表pivot table**实现。以 MySQL 为例一张中间表形如CREATE TABLE publisher_to_test ( id int(11) unsigned NOT NULL AUTO_INCREMENT, publisher_id int(11) DEFAULT NULL, test_id int(11) DEFAULT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8;中间表默认按双方实体名 _to_命名如publisher_to_test你可以通过在**拥有方owning side**的ManyToMany装饰器中指定pivotTable选项来自定义表名// 单向关系 ManyToMany({ entity: () Test, owner: true, pivotTable: publisher2test }) tests new CollectionTest(this); // 双向关系 ManyToMany({ entity: () BookTag, inversedBy: books, pivotTable: book2tag }) tags new CollectionBookTag(this);在运行时中间表数据的增删由 SQL 驱动内部的 PivotCollectionPersister 统一处理当 flush 一个含ManyToMany变更的实体时该模块会计算出中间表需要的插入、更新与删除集合保证双向关系两端与中间表数据保持一致。六、用 QueryBuilder 执行原生 SQL 查询当需要绕过 ORM 的对象映射、直接执行 SQL 时可以自己拼 SQL也可以使用QueryBuilder帮你在 TypeScript 中安全地构造查询const qb orm.em.createQueryBuilder(Author); qb.update({ name: test 123, type: PublisherType.GLOBAL }).where({ id: 123, type: PublisherType.LOCAL }); console.log(qb.getQuery()); // UPDATE publisher2 SET name ?, type ? WHERE id ? AND type ? console.log(qb.getParams()); // [test 123, PublisherType.GLOBAL, 123, PublisherType.LOCAL] // 执行查询 const res1 await qb.execute(); // 或者完全不用 QueryBuilder直接调用驱动执行原生 SQL const driver orm.em.getDriver(); const res2 await driver.execute(SELECT ? ?, [1, 2]);getQuery()返回带占位符?的 SQL 模板getParams()返回对应的参数数组——这种SQL 与参数分离的方式既避免了手工拼接注入风险也便于日志审计。从源码看这两个方法都由 QueryBuilder.toQuery() 驱动SQL 模板由内部的NativeQueryBuilder.compile()生成参数随之收集另外还有getFormattedQuery()把参数内联进 SQL 的便于打印的版本与toRaw()返回可嵌入其他查询的RawQueryFragment见 QueryBuilder.ts。QueryBuilder提供流畅fluent接口核心方法签名如下QueryBuilder.select(fields: string | string[], distinct?: boolean): QueryBuilder; QueryBuilder.insert(data: any): QueryBuilder; QueryBuilder.update(data: any): QueryBuilder; QueryBuilder.delete(cond: any): QueryBuilder; QueryBuilder.count(fields: string | string[], distinct?: boolean): QueryBuilder; QueryBuilder.join(field: string, alias?: string): QueryBuilder; QueryBuilder.leftJoin(field: string, alias?: string): QueryBuilder; QueryBuilder.where(cond: any, operator: $and | $or): QueryBuilder; QueryBuilder.andWhere(cond: any): QueryBuilder; QueryBuilder.orWhere(cond: any): QueryBuilder; QueryBuilder.groupBy(fields: string | string[]): QueryBuilder; QueryBuilder.having(cond: any): QueryBuilder; QueryBuilder.populate(populate: string[]): QueryBuilder; QueryBuilder.limit(limit: number, offset?: number): QueryBuilder; QueryBuilder.offset(offset: number): QueryBuilder; QueryBuilder.getQuery(): string; QueryBuilder.getParams(): any; QueryBuilder.clone(): QueryBuilder;完整的方法族含子查询、CTE、union、onConflict/upsert、orderBy、流式读取等定义在 QueryBuilder.ts 中仓库内还有大量可直接研读的测试例如 tests/features/query-builder/ 目录下的用例以及条件节点如何被翻译成 SQL 的 CriteriaNodeFactory。七、事务自动 flush 与显式transactional默认情况下em.flush()会把本次计算出的全部变更放在一个数据库事务里执行相关机制见 Unit of Work 文档因此大多数场景你不需要手动开启事务。当需要显式控制事务边界时使用em.transactional(cb)把回调放进事务中执行。事务会提供一个隔离 Identity Map 的 fork 出来的EntityManager作为回调参数——请务必用它来修改数据// 如果回调内部抛出错误回调内产生的所有数据库查询都会被回滚 await orm.em.transactional(async (em: EntityManager) { const god new Author(God, helloheaven.god); await em.persist(god).flush(); });从源码看transactional的实现位于 EntityManager.transactional()它先通过getContext(false)获取当前上下文若配置了disableTransactions则直接执行回调跳过事务否则交由TransactionManager处理回调的 begin/commit/rollback 生命周期底层连接层的事务原语begin/commit/rollback由 Connection.transactional() 提供。另外你还可以用em.begin()/em.commit()/em.rollback()手动管理事务上下文见 EntityManager.ts。更完整的用法嵌套事务、ctx参数、隔离级别、与 QueryBuilder 配合可参考 事务文档 和 tests/features/transactions/ 下的测试。八、LIKE 查询直接用 JavaScript 正则SQL 的LIKE查询可以直接用 JavaScript 原生正则表达式表达——MikroORM 会把正则编译为对应的 SQLLIKE模式例如.*→%、.→_const author1 new Author2(Author 1, a1example.com); const author2 new Author2(Author 2, a2example.com); const author3 new Author2(Author 3, a3example.com); await orm.em.persist([author1, author2, author3]).flush(); // 查找 email 形如 %exa%le.c_m 的作者 const authors await orm.em.find(Author2, { email: /exa.*le\.c.m$/ }); console.log(authors); // 三个作者全部命中正则 → SQLLIKE的转换逻辑由 QueryBuilder 条件节点在生成 WHERE 子句时处理相关实现可追溯到 CriteriaNode 系列ScalarCriteriaNode、ObjectCriteriaNode。注意这种写法依赖条件值的序列化管线因此仅在 SQL 驱动路径下生效MongoDB 的$regex语义略有不同。九、原生集合方法insert / nativeUpdate / nativeDelete当需要批量操作、或只想用初始数据填充数据库时走完整 ORM 流程实例化实体 → persist → flush会带来不必要的样板代码。此时可以直接使用insert/nativeUpdate/nativeDelete三个原生方法em.insertT extends AnyEntity(entityName: string, data: any): PromiseIPrimaryKey; em.nativeUpdateT extends AnyEntity(entityName: string, where: FilterQueryT, data: any): Promisenumber; em.nativeDeleteT extends AnyEntity(entityName: string, where: FilterQueryT | any): Promisenumber;这些方法基于实体元数据通过QueryBuilder生成并执行原生 SQL。请注意它们的语义边界不会把结果水合hydrate成实体对象也不会触发生命周期钩子lifecycle hooks。它们同样以快捷方式暴露在EntityRepository上EntityRepository.insert(data: any): PromiseIPrimaryKey; EntityRepository.nativeUpdate(where: FilterQueryT, data: any): Promisenumber; EntityRepository.nativeDelete(where: FilterQueryT | any): Promisenumber;从源码看这些方法最终都汇聚到 AbstractSqlDriver 的同名实现上nativeInsertL985通过qb.insert(data).execute(run, false)执行并返回主键复合主键按meta.primaryKeys顺序组装nativeUpdateL1429与nativeDeleteL1751则返回受影响行数EntityManager层面对应的封装位于 EntityManager.nativeUpdate/nativeDelete。另外nativeInsert还会自动处理数据中的ManyToMany中间表写入L1019这也是原生但懂关系的设计体现。除此之外还有execute()方法可以直接执行原始 SQL 字符串或QueryBuilder实例。要创建QueryBuilder可以在EntityManager与EntityRepository上使用createQueryBuilder()工厂方法const qb em.createQueryBuilder(Author); qb.select(*).where({ id: { $in: [...] } }); const res await em.getDriver().execute(qb); console.log(res); // 底层数据库驱动返回的未处理结果注意这里execute()返回的是底层驱动未经 ORM 加工的原始结果数组/行对象适合报表、导出等不需要实体映射的场景。十、各数据库平台的已知限制MS SQL ServerUUID 值以大写形式返回不支持级联路径中的环cycles in cascade pathsSchema 差异对比diffing能力有限没有对全文检索fulltext search的原生支持upsert 支持有限。Oracle不支持级联路径中的环外键没有ON UPDATE子句Oracle 原生不支持单条查询中不支持多条语句multiple statementsWHERE子句中不支持元组比较tuple comparison外键不会被自动建立索引。这两类限制分别体现在 mssql 驱动 与 oracledb 驱动 的平台实现中如 PostgreSqlPlatform 之类的平台类负责方言差异也反映在仓库对应方言的测试里例如 tests/features/schema-generator/ 下针对各数据库的 Schema 生成快照。实际项目选型时应结合这些边界评估功能可行性。总结面向 SQL 数据库MikroORM 给出了ORM 托管 原生 SQL双轨并行的完整方案通过mikro-orm/*驱动包一行命令接入 MySQL/MariaDB、PostgreSQL/CockroachDB、SQLite/libSQL、MSSQL 与 Oracle用MikroORM.init完成引导后即可享受em.flush()的自动事务、基于 pivot table 的ManyToMany、正则驱动的LIKE查询需要精细控制时QueryBuildergetQuery()/getParams()、transactional()回调、insert/nativeUpdate/nativeDelete原生方法以及driver.execute()又提供了从构建 SQL到直通驱动的完整降级路径。理解各数据库平台MSSQL、Oracle的固有局限能帮助你在选型与建模阶段提前规避坑点。相关源码与测试可分别从 packages/sql/src、packages/core/src/EntityManager.ts 与 tests/features/query-builder/ 深入研读。赞分享后端【免费下载链接】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 SQL 驱动实战MySQL、PostgreSQL 与 SQLite 的安装、初始化、QueryBuilder、事务与原生方法详解MikroORM SQL 驱动实战MySQL、PostgreSQL 与 SQLite 的安装、初始化、QueryBuilder、事务与原生方法详解 本文基于后端MikroORM SQL 驱动实战指南安装、初始化、事务、原生查询与各数据库差异MikroORM SQL 驱动实战指南安装、初始化、事务、原生查询与各数据库差异 MikroORM 是一款基于 Data Mapper、Unit of Wor后端使用 MikroORM 5.9 接入 MongoDB实体定义、事务、索引与原生集合操作完全指南使用 MikroORM 5.9 接入 MongoDB实体定义、事务、索引与原生集合操作完全指南 本篇指南以 MikroORM 5.9 官方文档 usage后端上一篇终极指南如何用ebook2audiobook将电子书转换为专业有声书下一篇OpenMV IDE在Ubuntu 22.04下无法启动的解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表