在 LoopBack 4 中使用 TypeORM:@loopback/typeorm 集成指南

发布时间:2026/10/15 7:47:32
在 LoopBack 4 中使用 TypeORM:@loopback/typeorm 集成指南
后端微服务【免费下载链接】loopback-nextLoopBack makes it easy to build modern API applications that require complex integrations.项目地址https://gitcode.com/gh_mirrors/lo/loopback-next点击查看免费下载导读本指南围绕loopback-next仓库中 extensions/typeorm/README.md 展开系统讲解如何在 LoopBack 4 应用中通过loopback/typeorm启用 TypeORM 作为 ORM 层替代默认的 Juggler ORM。读完本文你将掌握 TypeOrmMixin 的启用方式、Connection 与 Entity 的声明约定、控制器中免建 Repository 的依赖注入技巧以及该模块的启动生命周期、内置 Booter 原理与当前六项功能限制——并在此基础上能够独立搭建一个基于 TypeORM 的 LoopBack REST 应用。模块概览与定位loopback/typeorm是 LoopBack 4 官方 monorepo 中的扩展模块位于extensions/typeorm/它的目标非常明确把 TypeORM 的能力接入 LoopBack 应用。TypeORM 是一款基于 TypeScript 的 Node.js ORM支持 MySQL、PostgreSQL、SQLite、MongoDB 等众多数据库。在 LoopBack 语境下它可以作为默认 Juggler ORM 的替代方案让开发者继续使用 TypeORM 熟悉的数据访问 API同时保留 LoopBack 的依赖注入、Booter、REST 层等基础设施。需要特别强调的是该模块的稳定性标注为⚠️Experimental⚠️实验性包以0.x.y版本发布到 npm其 API 与功能可能在未来的发布中发生破坏性变更。仓库中 package.json 当前版本为0.11.16正是这一实验性策略的体现。安装与环境要求安装扩展包在项目根目录执行npm install --save loopback/typeorm依赖关系从 package.json 可以看到该模块的依赖设计peerDependencies宿主应用需自行安装loopback/boot^8.0.1loopback/core^7.0.0loopback/rest^15.0.1dependenciestypeorm^0.3.31、debug、tslibenginesNode.js22 || 24 || 26devDependencies中使用了sqlite3^6.0.1作为测试驱动的示例这意味着它是一个典型的 LoopBack 扩展本身并不重新实现 ORM而是把 TypeORM 的ConnectionManager、Connection、Repository等对象挂接到 LoopBack 的 Context依赖注入容器中。启用 TypeORM 支持TypeOrmMixin基本用法在应用类上应用TypeOrmMixin即可启用 TypeORM 支持import {BootMixin} from loopback/boot; import {RestApplication} from loopback/rest; import {TypeOrmMixin} from loopback/typeorm; export class MyApplication extends BootMixin(TypeOrmMixin(RestApplication)) { // ... }Mixin 的组合顺序遵循 LoopBack 惯例BootMixin(TypeOrmMixin(RestApplication))即先应用 TypeORM 能力再叠加 Boot 能力最终得到一个既支持自动 Boot、又具备 TypeORM 连接管理能力的 REST 应用。仓库中的测试夹具 application.ts 正是这种写法。Mixin 内部做了什么查看 typeorm.mixin.ts 的源码实现可以清晰看到TypeOrmMixin为应用类注入了三类核心能力注册TypeOrmComponent构造函数中调用this.component(TypeOrmComponent)组件声明了自身的 Bindings 与生命周期观察者详见下文生命周期一节。创建并绑定 ConnectionManager实例化一个ConnectionManager来自typeorm并将其绑定到TypeOrmBindings.MANAGER键为services.TypeOrmConnectionManager定义见 typeorm.keys.ts。此后应用内任何地方都能通过依赖注入获取到唯一的连接管理器。暴露connection()方法与migrateSchema()方法connection(connectionConfig)方法接收ConnectionOptions调用connectionManager.create(connectionConfig)创建连接对象并以connection.connectionName为键、typeOrmConnection为标签动态绑定到 Context绑定值为() this.connectionManager.get(name)migrateSchema()目前直接抛出TypeORM migration not implemented.对应 README Limitations 中数据库迁移尚未支持的说明。Mixin 单元测试 验证了TypeOrmMixin添加了connectionManager、connection、migrateSchema三个成员与我们上面的分析一致。创建连接ConnectionConnection 与 DataSource 的对应关系在 TypeORM 中Connection 负责数据库的连接与配置信息在 LoopBack 语境下它等价于 Juggler 中的 DataSource数据源。约定如下连接文件以.connection.ts为扩展名并放置在项目的typeorm-connections目录中。这一约定并非空谈——它直接对应 Booter 的默认配置详见下文Booter 自动加载一节。以下是一个 SQLite 连接的示例源自 README与测试夹具 sqlite.connection.ts 结构一致// src/typeorm-connections/sqlite.connection.ts import path from path; import {ConnectionOptions} from loopback/typeorm; import {Book} from ../typeorm-entities/; export const SqliteConnection: ConnectionOptions { name: SQLite, type: sqlite, database: ./mydb.sql, entities: [Book], synchronize: true, };ConnectionOptions直接复用typeorm的类型定义该模块通过 typeorm.types.ts 全量 re-export 了typeorm因此所有 TypeORM 支持的类型名与驱动参数在这里都有效字段含义备注name连接名称必须唯一会作为绑定键connection.name的一部分后续注入 Repository 时也靠它定位连接type数据库类型如sqlite、mysql、postgres、mongodb等需与已安装驱动匹配database数据库文件/库名对 SQLite 是文件路径对其他数据库是库名entities实体类数组也可以使用 glob 字符串路径让 TypeORM 自动发现实体synchronize是否自动同步表结构开发环境常用true生产环境建议关闭并配合迁移安装底层数据库驱动TypeORM 本身不捆绑数据库驱动需要手动安装。README 明确要求使用 SQLite 就安装sqlite3npm install sqlite3使用其他数据库时参考 TypeORM 官方文档安装对应的驱动如mysql2、pg、mongodb等。关于 TypeORM 支持的全部数据库及驱动清单请查阅 TypeORM 官方安装文档。注册连接在application.ts中通过this.connection(...)显式注册import {BootMixin} from loopback/boot; import {RestApplication} from loopback/rest; import {TypeOrmMixin} from loopback/typeorm; export class MyApplication extends BootMixin(TypeOrmMixin(RestApplication)) { constructor(options) { super(options); this.connection(SqliteConnection); // ... } }Booter 自动加载推荐做法除了手动this.connection()注册loopback/typeorm还内置了TypeOrmConnectionBooter它继承自loopback/boot的BaseArtifactBooter见 typeorm-connection.booter.ts在应用调用app.boot()时自动完成连接的发现与注册。其默认扫描规则由ConnectionDefaults定义export const ConnectionDefaults: ArtifactOptions { dirs: [typeorm-connections], extensions: [.connection.js], nested: true, };即扫描typeorm-connections目录下所有.connection.js对应编译前的.connection.ts文件且支持嵌套子目录。load()阶段会逐个require发现到的文件遍历其导出的连接配置并调用app.connection(connection)完成绑定如果应用类没有应用TypeOrmMixin缺少app.connection()Booter 会打印警告提示先添加 Mixin。Booter 单元测试 覆盖了三条关键行为未启用 Mixin 时给出警告未传配置时使用ConnectionDefaults传入部分配置时与默认值合并nested仍保持默认trueload()后应用中出现以typeOrmConnection标签绑定的连接测试中预期键为connection.my-db。集成测试 则验证了app.boot()之后app.findByTag(TypeOrmBindings.TAG)能取到connection.my-db绑定说明目录约定 Booter 自动注册这条路径是开箱即用的。创建实体EntityEntity 等价于 LoopBack 的 Model。约定实体文件放在项目的typeorm-entities目录中并使用 TypeORM 原生的装饰器语法定义// src/typeorm-entities/book.entity.ts import {Entity, Column, PrimaryColumn} from typeorm; Entity() export class Photo { PrimaryColumn() id: number; Column() title: string; Column() isPublished: boolean; }需要留意的是README 这个示例中类名写成了Photo实体名与字段名存在笔误更规范、可直接运行的示例是测试夹具 book.entity.tsimport {Column, Entity, PrimaryGeneratedColumn} from loopback/typeorm; Entity() export class Book { PrimaryGeneratedColumn() id: number; Column() title: string; Column() published: boolean; }两者唯一的差异是主键装饰器PrimaryGeneratedColumn()表示自增主键插入时由数据库生成更贴近 CRUD 场景PrimaryColumn()则要求应用自行赋值主键。loopback/typeorm因为 re-export 了typeorm所以直接import {Entity, Column, ...} from loopback/typeorm也是可行的测试夹具即如此。创建控制器并注入 Repository免建 Repositorytypeorm.repository 装饰器这是loopback/typeorm最大的便利点不需要为实体手写 Repository 类——TypeORM 会自动为每个实体生成 Repository开发者只需在控制器中注入即可。注入后拿到的 Repository API 与 TypeORM 原生 repository API 完全一致save、find、findOne、findAndCount等。控制器示例源自 README字段做了轻微补全以保持代码可编译性// src/controllers/book.controller.ts import {get, post, param, Request, requestBody} from loopback/rest; import {getModelSchema, Repository, typeorm} from loopback/typeorm; import {Book} from ../typeorm-entities; export class BookController { typeorm.repository(Book) private bookRepo: RepositoryBook; constructor() {} // 创建一本书 post(/book) async create(requestBody() data: Book) { const book new Book(); book.title data.title; book.published false; return await this.bookRepo.save(book); } // 按标题查找 get(/book/{title}) async findByTitle(param.path.string(title) title: string) { return await this.bookRepo.find({title}); } }README 原示例中get(/note/{title})与find({title})属于从其他示例复制时的笔误正文已按路由/book/{title}修正param.path.string需从loopback/rest导入。装饰器的底层原理typeorm.repository(entity, connectionName?)的实现位于 typeorm.decorators.ts。它本质上是一个带自定义解析逻辑的inject装饰器解析时先从 Context 中取出TypeOrmBindings.MANAGER即绑定在应用上的ConnectionManager再通过manager.get(connectionName)获取指定名称的连接最后调用conn.getRepository(entity)返回该实体的 Repository。因此未指定connectionName时使用默认连接TypeORM 的manager.get()默认行为应用配置了多个连接时可以通过第二个参数精确指定例如测试夹具中typeorm.repository(Book, my-db)。实体与 OpenAPI Schema 的转换getModelSchema控制器中定义 REST 端点时需要为请求体/响应体提供 OpenAPI schema。loopback/typeorm提供了getModelSchema(modelCtor, options?)工具函数见 typeorm.utils.ts用于把 TypeORM 实体转换为 OpenAPISchemaObject内部通过getMetadataArgsStorage().columns拿到全局列元数据过滤出目标实体的列自动跳过带primary选项的列即PrimaryGeneratedColumn/PrimaryColumn声明的列将列的类型经getStringifiedType映射为 OpenAPI 类型使用WeakMap缓存转换结果避免重复计算支持JsonSchemaOptions如title、exclude: [id]、includeRelations等具体选项与loopback/rest的 schema 选项一致。测试夹具 book.controller.ts 演示了完整用法——POST /books的响应体用getModelSchema(Book)请求体用getModelSchema(Book, {title: NewUser, exclude: [id]})GET /books/{id}用getModelSchema(Book, {includeRelations: true})。这恰好对应下面限制小节提到的实体 schema 能力现状。生命周期与启动流程TypeOrmMixin注册的TypeOrmComponent见 typeorm.mixin.ts声明了两个关键元素BindingsTypeOrmConnectionBooter通过createBindingFromClass注册LifeCycleObserversTypeOrmLifeCycleManager。TypeOrmLifeCycleManager以lifeCycleObserver(datasource, {scope: BindingScope.SINGLETON})声明注入了ConnectionManager并实现start()对manager.connections中所有连接执行c.connect()并行stop()对所有连接执行c.close()。这意味着连接的建立与释放完全纳入 LoopBack 应用生命周期应用start()时自动连接数据库应用stop()时自动关闭连接无需手动管理连接池的启停。整体启动时序可以概括为应用构造TypeOrmMixin创建ConnectionManager并绑定app.boot()TypeOrmConnectionBooter扫描typeorm-connections目录逐个注册连接绑定或使用this.connection()手动注册app.start()TypeOrmLifeCycleManager.start()并行建立所有连接控制器中typeorm.repository(entity)注入时从管理器取出对应连接的 Repositoryapp.stop()并行关闭全部连接。限制与注意事项README 明确指出当前实现尚不支持以下能力对应上游跟踪的六项议题社区贡献欢迎完整的 TypeORM 到 OpenAPI 数据类型转换目前getStringifiedType仅支持Number → number、String → string、Boolean → boolean见 typeorm.utils.ts 中的 TODO 注释其他类型如Date、json、decimal等会被跳过并输出 debug 日志。实体的完整 JSON/OpenAPI schema包括带/不带 id、带/不带关系、partial 等变体尚未完整生成目前getModelSchema会跳过主键列。LoopBack 风格过滤器filterWhereFilter、include、fields等 LoopBack 查询语法不支持需使用 TypeORM 原生的find({where, relations})写法。描述 filter 格式的 JSON/OpenAPI schema。自定义 Repository 类例如bookRepo.findByTitle(title)这类带业务方法的自定义 Repository 尚不支持只能使用 TypeORM 自动生成的 Repository这也解释了为什么装饰器直接注入RepositoryBook。数据库迁移migrateSchema()抛出不支持异常表结构同步目前只能依赖连接配置中的synchronize: true仅适合开发/演示。使用建议该模块适合快速原型与中小型项目若项目强依赖 LoopBack filter、模型迁移或复杂 schema 生成建议评估loopback/repositoryJuggler或等待上述能力落地。测试与验证在仓库根目录执行npm test即可运行全部测试。与loopback/typeorm相关的测试集中在 extensions/typeorm/src/testsunit/mixin.unit.ts验证 Mixin 添加connectionManager、connection、migrateSchemaunit/booter.unit.ts验证默认扫描规则、配置合并、无 Mixin 时的警告、load 阶段的绑定integration/booter.integration.ts验证app.boot()后connection.my-db绑定存在integration/rest.integration.ts端到端验证POST /books创建实体、GET /books/{id}按 id 获取实体覆盖了实体定义 → 连接注册 → Booter 发现 → 控制器注入 Repository → REST 请求的完整链路。从 package.json 可见测试依赖loopback/testlab、sqlite3pretest阶段会先执行lb-tsc构建再以lb-mocha运行。进一步阅读模块 READMEextensions/typeorm/README.mdMixin 与组件实现typeorm.mixin.ts连接 Bootertypeorm-connection.booter.tsRepository 注入装饰器typeorm.decorators.tsOpenAPI schema 转换工具typeorm.utils.ts绑定键定义typeorm.keys.ts完整可运行示例测试夹具fixtures 目录包元数据与依赖声明package.json若需本地体验可直接安装loopback/typeorm并参照本文的 Mixin 连接 实体 控制器四步搭建一个最小应用配合npm test验证链路是否打通。赞分享后端微服务【免费下载链接】loopback-nextLoopBack makes it easy to build modern API applications that require complex integrations.项目地址https://gitcode.com/gh_mirrors/lo/loopback-next点击查看免费下载相关推荐在 LoopBack 4 中挂载 LoopBack 3 应用loopback/booter-lb3app 实战指南在 LoopBack 4 中挂载 LoopBack 3 应用loopback/booter lb3app 实战指南 导读 LoopBack 3LB3与后端微服务使用 loopback/cron 在 LoopBack 4 应用中调度定时任务使用 loopback/cron 在 LoopBack 4 应用中调度定时任务 loopback/cron 是 LoopBack 4 官方提供的定时任务扩展后端微服务在 LoopBack 4 应用中使用 loopback/cron 组件运行定时任务在 LoopBack 4 应用中使用 loopback/cron 组件运行定时任务 本文围绕 loopback/cron 扩展组件系统讲解如何在 Loop后端微服务上一篇3分钟免费搞定Figma中文界面设计师必备的终极本地化解决方案下一篇如何快速实现网站全量备份HTTrack离线浏览完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考