TypeORM 是一个ORM框架,它可以运行在 NodeJS、Browser、Cordova、PhoneGap、Ionic、React Native、Expo 和 Electron 平台上,可以与 TypeScript 和 JavaScript (ES5,ES6,ES7,ES8)一起使用。 它的目标是始终支持最新的 JavaScript 特性并提供额外的特性以帮助你开发任何使用数据库的(不管是只有几张表的小型应用还是拥有多数据库的大型企业应用)应用程序。
不同于现有的所有其他 JavaScript ORM 框架,TypeORM 支持 Active Record 和 Data Mapper 模式,这意味着你可以以最高效的方式编写高质量的、松耦合的、可扩展的、可维护的应用程序。
TypeORM 参考了很多其他优秀 ORM 的实现, 比如 Hibernate, Doctrine 和 Entity Framework。
TypeORM 的一些特性:
- 支持 DataMapper 和 ActiveRecord (随你选择)
- 实体和列
- 数据库特性列类型
- 实体管理
- 存储库和自定义存储库
- 清晰的对象关系模型
- 关联(关系)
- 贪婪和延迟关系
- 单向的,双向的和自引用的关系
- 支持多重继承模式
- 级联
- 索引
- 事务
- 迁移和自动迁移
- 连接池
- 主从复制
- 使用多个数据库连接
- 使用多个数据库类型
- 跨数据库和跨模式查询
- 优雅的语法,灵活而强大的 QueryBuilder
- 左联接和内联接
- 使用联查查询的适当分页
- 查询缓存
- 原始结果流
- 日志
- 监听者和订阅者(钩子)
- 支持闭包表模式
- 在模型或者分离的配置文件中声明模式
- json / xml / yml / env 格式的连接配置
- 支持 MySQL / MariaDB / Postgres / SQLite / Microsoft SQL Server / Oracle / sql.js
- 支持 MongoDB NoSQL 数据库
- 可在 NodeJS / 浏览器 / Ionic / Cordova / React Native / Expo / Electron 平台上使用
- 支持 TypeScript 和 JavaScript
- 生成高性能、灵活、清晰和可维护的代码
- 遵循所有可能的最佳实践
- 命令行工具
还有更多...
通过使用 你的 看起来像这样:
逻辑操作就像是这样:
或者,如果你更喜欢使用实现,也可以这样用:
逻辑操作如下所示:
- 通过安装:
- 你还需要安装 :
并且需要在应用程序的全局位置导入(例如在中)
- 你可能还需要安装 node typings(以此来使用 Node 的智能提示):
- 安装数据库驱动:
- MySQL 或者 MariaDB
(也可以安装 )
- PostgreSQL
- SQLite
- Microsoft SQL Server
- sql.js
- Oracle
根据你使用的数据库,仅安装其中一个即可。 要使 Oracle 驱动程序正常工作,需要按照其站点中的安装说明进行操作。
- MongoDB (试验性)
- NativeScript, react-native 和 Cordova
查看 支持的平台
- MySQL 或者 MariaDB
此外,请确保你使用的是 TypeScript 编译器版本2.3或更高版本,并且已经在中启用了以下设置:
你可能还需要在编译器选项的中启用,或者从安装。
开始使用 TypeORM 的最快方法是使用其 CLI 命令生成启动项目。 只有在 NodeJS 应用程序中使用 TypeORM 时,此操作才有效。如果你使用的是其他平台,请继续执行分步指南。
首先全局安装 TypeORM:
然后转到要创建新项目的目录并运行命令:
其中是项目的名称,是您将使用的数据库。
数据库可以是以下值之一: , , , , , , , , , , .
此命令将在目录中生成一个包含以下文件的新项目:
你还可以在现有 node 项目上运行,但要注意,此操作可能会覆盖已有的某些文件。
接下来安装项目依赖项:
在安装过程中,编辑文件并在其中放置您自己的数据库连接配置选项:
绝大多数情况下,你只需要配置 , , , 或者 。
完成配置并安装所有 node modules 后,即可运行应用程序:
至此你的应用程序应该成功运行并将新用户插入数据库。你可以继续使用此项目并集成所需的其他模块并创建更多实体。
你可以通过运行来生成一个更高级的 Express 项目
您对 ORM 有何期待?您期望它将为您创建数据库表,并且无需编写大量难以维护的 SQL 语句来查找/插入/更新/删除您的数据。本指南将向您展示如何从头开始设置 TypeORM 并实现这些操作。
使用数据库从创建表开始。如何告诉 TypeORM 创建数据库表?答案是 - 通过模型。 应用程序中的模型即是数据库中的表。
举个例子, 你有一个 模型:
并且希望将 photos 存储在数据库中。要在数据库中存储内容,首先需要一个数据库表,并从模型中创建数据库表。但是并非所有模型,只有您定义为entities的模型。
Entity是由装饰器装饰的模型。将为此类模型创建数据库表。你可以使用 TypeORM 处理各处的实体,可以使用它们 load/insert/update/remove 并执行其他操作。
让我们将模型作为一个实体
现在,将为实体创建一个数据库表,我们将能够在应用程序中的任何位置使用它。 我们已经创建了一个数据库表,但是没有哪个字段属于哪一列,下面让我们在数据库表中创建几列。
要添加数据库列,你只需要将要生成的实体属性加上装饰器。
现在 , , , , 和 列将会被添加到表中。 数据库中的列类型是根据你使用的属性类型推断的,例如: 将被转换为,将转换为,转换为等。但你也可以通过在装饰器中隐式指定列类型来使用数据库支持的任何列类型。
我们已经生成了一个包含列的数据库表,但还剩下一件事。每个数据库表必须具有包含主键的列。
每个实体必须至少有一个主键列。这是必须的,你无法避免。要使列成为主键,您需要使用装饰器。
假设你希望 id 列自动生成(这称为 auto-increment/sequence/serial/generated identity column)。为此你需要将装饰器更改为装饰器:
接下来,让我们修复数据类型。默认情况下,字符串被映射到一个 varchar(255)类型(取决于数据库类型)。 数字被映射到一个类似整数类型(取决于数据库类型)。但是我们不希望所有的列都是有限的 varchars 或整数,让我们修改下代码以设置想要的数据类型:
列类型是特定于数据库的。你可以设置数据库支持的任何列类型。有关支持的列类型的更多信息,请参见此处。
当实体被创建后,让我们创建一个(或,无论你怎么命名)文件,并配置数据库连接::
我们在此示例中使用 MySQL,你可以使用任何其他受支持的数据库。要使用其他数据库,只需将选项中的更改为希望使用的数据库类型:mysql,mariadb,postgres,sqlite,mssql,oracle,cordova,nativescript,react-native,expo 或 mongodb。同时还要确保 host, port, username, password 和数据库设置的正确性。
我们将 Photo 实体添加到此连接的实体列表中。所有需要在连接中使用的每个实体都必须加到这个表中。
设置可确保每次运行应用程序时实体都将与数据库同步。
之后当我们创建更多实体时,都需要将一一它们添加到配置中的实体中,但是这不是很方便,所以我们可以设置整个目录,从中连接所有实体并在连接中使用:
但要小心这种方法。 如果使用的是,则需要指定文件的路径。 如果使用的是,那么需要在目录中指定文件的路径。 如果使用,当你删除或重命名实体时,请确保清除目录并再次重新编译项目,因为当你删除源文件时,其编译的版本不会从输出目录中删除,并且 TypeORM 依然会从中加载这些文件,从而导致异常。
现在可以启动,启动后可以发现数据库自动被初始化,并且 Photo 这个表也会创建出来。
现在创建一个新的 photo 存到数据库:
保存实体后,它将获得新生成的 ID。 方法返回传递给它的同一对象的实例。但它不是对象的新副本,只是修改了它的"id"并返回它。
我们可以使用最新的 ES8(ES2017)功能,并使用 async / await 语法代替:
我们刚创建了一张新 photo 并将其保存在数据库中。使用你可以操纵应用中的任何实体。
例如,加载已经保存的实体:
是一个 Photo 对象数组,其中包含从数据库加载的数据。
了解更多有关 EntityManager 的信息。
现在让我们重构之前的代码,并使用而不是。每个实体都有自己的存储库,可以处理其实体的所有操作。当你经常处理实体时,Repositories 比 EntityManagers 更方便使用:
了解更多有关 Repository 的信息。
让我们使用 Repository 尝试更多的加载操作:
让我们从数据库加载出 photo,更新并保存到数据库:
这个的 photo 在数据库中就成功更新了。
让我们从数据库中删除我们的 Photo:
这个的 photo 在数据库中被移除了。
让我们与另一个类创建一对一的关系。先在中创建一个新类。此 PhotoMetadata 类应包含 photo 的其他元信息:
这里我们使用了一个名为的新装饰器,它允许我们在两个实体之间创建一对一的关系。 是一个函数,返回我们想要与之建立关系的实体的类。由于特定于语言的关系,我们只能使用一个返回类的函数,而不是直接使用该类。 同时也可以把它写成,但是显得代码更有可读性。type 变量本身不包含任何内容。
我们还添加了一个装饰器,表明实体键的对应关系。关系可以是单向的或双向的。但是只有一方是拥有者。在关系的所有者方面需要使用@JoinColumn 装饰器。
如果运行该应用程序,你将看到一个新生成的表,它将包含一个带有关系外键的列:
现在来创建一个 photo,它的元信息将它们互相连接起来。
关系可以是单向的或双向的。目前 PhotoMetadata 和 Photo 之间的关系是单向的。关系的所有者是 PhotoMetadata,而 Photo 对 PhotoMetadata 一无所知。这使得从 Photo 中访问 PhotoMetadata 变得很复杂。要解决这个问题,我们应该在 PhotoMetadata 和 Photo 之间建立双向关系。让我们来修改一下实体:
是用来指定反向关系的名称。Photo 类的元数据属性是在 Photo 类中存储 PhotoMetadata 的地方。你可以选择简单地将字符串传递给装饰器,而不是传递返回 photo 属性的函数,例如。这种函数类型的方法使我们的重构更容易。
注意,我们应该仅在关系的一侧使用装饰器。你把这个装饰者放在哪一方将是这段关系的拥有方。关系的拥有方包含数据库中具有外键的列。
在一个查询中加载 photo 及 photo metadata 有两种方法。使用或使用。我们先使用方法。 方法允许你使用 / 接口指定对象。
photos 将包含来自数据库的 photos 数组,每个 photo 将包含其 photo metadata。详细了解本文档中的查找选项。
使用查找选项很简单,但是如果你需要更复杂的查询,则应该使用。 允许以更优雅的方式使用更复杂的查询:
允许创建和执行几乎任何复杂性的 SQL 查询。使用时,请考虑创建 SQL 查询。在此示例中,"photo"和"metadata"是应用于所选 photos 的 别名。你可以使用别名来访问所选数据的列和属性。
我们可以在关系中设置选项,这是就可以在保存其他对象的同时保存相关对象。让我们更改一下的 photo 的装饰器:
使用允许就不需要边存 photo 边存元数据对象。我们可以简单地保存一个 photo 对象,由于使用了 cascade,metadata 也将自动保存。
让我们创建一个多对一/一对多的关系。假设一个 photo 有一个 author,每个 author 都可以有多个 photos。首先让我们创建一个类:
包含反向关系。 总是反向的, 并且总是与 一起出现。
现在让我们将关系的所有者方添加到 Photo 实体中:
在多对一/一对多的关系中,拥有方总是多对一的。这意味着使用的类将存储相关对象的 id。 运行应用程序后,ORM 将创建表:
它还将修改表,添加新的列并为其创建外键:
假设一个 photo 可以放在多个 albums 中,每个 albums 可以包含多个 photo。让我们创建一个类:
需要指定这是关系的所有者方。
现在添加反向关系到类:
运行后,ORM 将创建album_photos_photo_albums_联结表。
记得在 ORM 中使用 ConnectionOptions 注册类:
现在让我们将 albums 和 photos 插入我们的数据库:
如下所示:
你可以使用 QueryBuilder 构建几乎任何复杂性的 SQL 查询。例如,可以这样做:
此查询选择所有 published 的 name 等于"My"或"Mishka"的 photos。它将从结果中的第 5 个(分页偏移)开始,并且仅选择 10 个结果(分页限制)。得到的结果将按 ID 降序排序。photo 的 albums 将被 left-joined,其元数据将被 inner joined。
由于 QueryBuilder 的自由度更高,因此在项目中可能会大量的使用它。 更多关于 QueryBuilder 的信息,可查看。
查看示例用法。
下面这些 repositories 可以帮助你快速开始:
- Example how to use TypeORM with TypeScript
- Example how to use TypeORM with JavaScript
- Example how to use TypeORM with JavaScript and Babel
- Example how to use TypeORM with TypeScript and SystemJS in Browser
- Example how to use Express and TypeORM
- Example how to use Koa and TypeORM
- Example how to use TypeORM with MongoDB
- Example how to use TypeORM in a Cordova/PhoneGap app
- Example how to use TypeORM with an Ionic app
- Example how to use TypeORM with React Native
- Example how to use TypeORM with Electron using JavaScript
- Example how to use TypeORM with Electron using TypeScript
这几个扩展可以简化 TypeORM 的使用,并将其与其他模块集成:
- TypeORM + GraphQL framework
- TypeORM integration with TypeDI
- TypeORM integration with routing-controllers
- 从现有数据库生成模型 - typeorm-model-generator
了解如何贡献这里以及如何设置开发环境这里。
感谢所有贡献者:
开源既困难又耗时。 如果你想投资 TypeORM 的未来,你可以成为赞助商,让我们的核心团队花更多时间在 TypeORM 的改进和新功能上。成为赞助商
成为金牌赞助商,并从我们的核心贡献者那里获得高级技术支持。 成为金牌赞助商
- 连接
- 什么是
- 创建新的连接
- 使用
- 使用连接
只有在建立连接后才能与数据库进行交互。 TypeORM 的不会像看起来那样设置单个数据库连接,而是设置连接池。 如果你对数据库连接感兴趣,请参阅文档。 的每个实例都是一个独立的数据库连接。一旦调用的方法,就建立连接池设置。 如果使用函数设置连接,则会自动调用方法。调用时会断开连接(关闭池中的所有连接)。 通常情况下,你只能在应用程序启动时创建一次连接,并在完全使用数据库后关闭它。实际上,如果要为站点构建后端,并且后端服务器始终保持运行,则不需要关闭连接。
有多种方法可以创建连接。但是最简单和最常用的方法是使用和函数。
创建单个连接:
只使用和也可以进行连接。
创建多个连接:
这两种方式都根据你传递的连接选项创建,并调用方法。另外你也可以在项目的根目录中创建一个文件,和将自动从此文件中读取连接选项。项目的根目录与目录的级别相同。
不同的连接必须具有不同的名称。默认情况下,如果未指定连接名称,则为。 通常在你使用多个数据库或多个连接配置时才会使用多连接。
创建连接后,你可以使用函数从应用程序中的任何位置使用它:
应避免额外创建 classes/services 来存储和管理连接。此功能已嵌入到 TypeORM 中 - 无需过度工程并创建无用的抽象。
你可以使用类创建连接。例如:
这不是常规创建连接的方法,但它可能对某些用户有用。例如,想要创建连接并存储其实例,同时控制何时建立实际"connection"。你还可以创建和维护自己的:
但请注意,使用该方式,你将无法再使用 - 你需要存储连接管理器实例,并使用来获取所需的连接。
通常情况下为避免应用程序中出现不必要的复杂情况,应尽量少使用此方法,除非你确实认为需要时才使用。
设置连接后,可以使用函数在应用程序的任何位置使用它:
你也可以使用来获取连接,但在大多数情况下使用就足够了。
使用 Connection,你可以对实体执行数据库操作,尤其是使用连接的和。 有关它们的更多信息,请参阅Entity Manager 和 Repository 文档。
但一般来说,你不要太多使用。大多数情况下,你只需创建连接并使用和来访问连接的管理器和存储库,而无需直接使用连接对象:
- 使用多个连接
- 在单个连接中使用多个数据库
- 在单个连接中使用多个模式
- 主从复制
使用多个数据库的最简单方法是创建不同的连接:
此方法允许你连接到已拥有的任意数量的数据库,每个数据库都有自己的配置,自己的实体和整体ORM范围和设置。
对于每个连接,将创建一个新的实例。 你必须为创建的每个连接指定唯一的名称。
也可以从ormconfig文件加载所有连接选项:
指定要按名称创建的连接:
使用连接时,必须指定连接名称以获取特定连接:
使用此方法的好处是你可以使用不同的登录凭据,主机,端口甚至数据库类型来配置多个连接。
但是缺点可能是需要管理和使用多个连接实例。
如果你不想创建多个连接,但是想在一个连接中使用多个数据库,则可以指定使用的每个实体的数据库名称:
实体将在数据库内创建,实体则在数据库内。
如果要从其他数据库中选择数据,则只需提供一个实体:
此代码将生成以下sql查询(取决于数据库类型):
还可以指定表而不是实体:
仅在mysql和mssql数据库中支持此功能。
你可以在应用程序中使用多个模式,只需在每个实体上设置:
实体将在 schema中创建,实体将在 schema中创建。
其他实体将在默认连接架构中创建。
如果要从其他模式中选择数据,则只需提供一个实体:
此代码将生成以下sql查询(取决于数据库类型):
你还可以指定表而不是实体:
仅在postgres和mssql数据库中支持此功能。
在mssql中,你还可以组合模式和数据库,例如:
你可以使用TypeORM设置读/写复制。
复制连接设置示例:
所有模式更新和写入操作都使用服务器执行。 find方法或select query builder执行的所有简单查询都使用随机的实例。
如果要在查询构建器创建的SELECT中显式使用master,可以使用以下代码:
请注意,需要显式释放由创建的连接。
mysql,postgres和sql server数据库都支持复制。
Mysql支持深度配置:
- 实体是什么?
- 实体列
- 主列
- 特殊列
- 空间列
- 列类型
- /的列类型
- 的列类型
- ///的列类型
- 的列类型
- 的列类型
- 列类型
- 的列类型
- 列类型
- 具有生成值的列
- 列选项
实体是一个映射到数据库表(或使用 MongoDB 时的集合)的类。 你可以通过定义一个新类来创建一个实体,并用来标记:
这将创建以下数据库表:
基本实体由列和关系组成。 每个实体必须有一个主列(如果使用 MongoDB,则为 ObjectId 列)。
每个实体都必须在连接选项中注册:
或者你可以指定包含所有实体的整个目录, 该目录下所有实体都将被加载:
如果要为实体使用替代表名,可以在中指定:。 如果要为应用程序中的所有数据库表设置基本前缀,可以在连接选项中指定。
使用实体构造函数时,其参数必须是可选的。 由于 ORM 在从数据库加载时才创建实体类的实例,因此在此之前并不知道构造函数的参数。
在Decorators reference中了解有关参数@Entity 的更多信息。
由于数据库表由列组成,因此实体也必须由列组成。 标有的每个实体类属性都将映射到数据库表列。
每个实体必须至少有一个主列。 有几种类型的主要列:
- 创建一个主列,它可以获取任何类型的任何值。你也可以指定列类型。 如果未指定列类型,则将从属性类型自动推断。
下面的示例将使用类型创建 id,你必须在保存之前手动分配。
- 创建一个主列,该值将使用自动增量值自动生成。 它将使用 / /创建列(取决于数据库)。 你不必在保存之前手动分配其值,该值将会自动生成。
- 创建一个主列,该值将使用自动生成。 Uuid 是一个独特的字符串 id。 你不必在保存之前手动分配其值,该值将自动生成。
你也可以拥有复合主列:
当您使用保存实体时,它总是先尝试使用给定的实体 ID(或 ids)在数据库中查找实体。 如果找到 id / ids,则将更新数据库中的这一行。 如果没有包含 id / ids 的行,则会插入一个新行。
要通过 id 查找实体,可以使用或。 例:
有几种特殊的列类型可以使用:
- 是一个特殊列,自动为实体插入日期。无需设置此列,该值将自动设置。
- 是一个特殊列,在每次调用实体管理器或存储库的时,自动更新实体日期。无需设置此列,该值将自动设置。
- 是一个特殊列,在每次调用实体管理器或存储库的时自动增长实体版本(增量编号)。无需设置此列,该值将自动设置。
MS SQL,MySQL/MariaDB 和 PostgreSQL 都支持 Spatial 列。由于各数据库列名不同,TypeORM 对数据库的支持略有差异。
MS SQL 和 MySQL/MariaDB 的 TypeORM 支持well-known text(WKT)的 geometries,因此 geometry 列 应该是用类型标记。
TypeORM 的 PostgreSQL 支持使用GeoJSON作为交换格式,因此 geometry 列应在导入后标记为或(或子类,例如)。
TypeORM尝试做正确的事情,但并不总是能够确定何时插入的值或PostGIS函数的结果应被视为几何。 因此,你可能会发现自己编写的代码类似于以下代码,其中值从GeoJSON转换为PostGIS ,并作为转换为GeoJSON:
TypeORM 支持所有最常用的数据库支持的列类型。 列类型是特定于数据库类型的 - 这为数据库架构提供了更大的灵活性。 你可以将列类型指定为的第一个参数 或者在的列选项中指定,例如:
或
如果要指定其他类型参数,可以通过列选项来执行。 例如:
或
, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , , , , , , , , , , , , , ,
和都支持列类型。 并有多种列定义方式:
使用typescript枚举:
注意:支持字符串,数字和异构枚举。
使用带枚举值的数组:
有一种称为的特殊列类型,它可以将原始数组值存储在单个字符串列中。 所有值都以逗号分隔。 例如:
存储在单个数据库列中的值。 当你从数据库加载数据时,name 将作为 names 数组返回,就像之前存储它们一样。
注意不能在值里面有任何逗号。
还有一个名为的特殊列类型,它可以存储任何可以通过 JSON.stringify 存储在数据库中的值。 当你的数据库中没有 json 类型而你又想存储和加载对象,该类型就很有用了。 例如:
存储在单个数据库列中的值 当你从数据库加载数据时,将通过 JSON.parse 返回 object/array/primitive。
你可以使用装饰器创建具有生成值的列。 例如:
值将自动生成并存储到数据库中。
除了"uuid"之外,还有"increment"生成类型,但是对于这种类型的生成,某些数据库平台存在一些限制(例如,某些数据库只能有一个增量列,或者其中一些需要增量才能成为主键)。
列选项定义实体列的其他选项。 你可以在上指定列选项:
中可用选项列表:
- - 列类型。其中之一在上面.
- - 数据库表中的列名。
默认情况下,列名称是从属性的名称生成的。 你也可以通过指定自己的名称来更改它。
- - 列类型的长度。 例如,如果要创建类型,请指定列类型和长度选项。
- - 列类型的显示范围。 仅用于MySQL integer types
- - 触发器。 仅用于 MySQL.
- - 在数据库中使列或。 默认情况下,列是。
- - 指示"save"操作是否更新列值。如果为false,则只能在第一次插入对象时编写该值。 默认值为"true"。
- - 定义在进行查询时是否默认隐藏此列。 设置为时,列数据不会显示标准查询。 默认情况下,列是
- - 添加数据库级列的值。
- - 将列标记为主要列。 使用方式和相同。
- - 将列标记为唯一列(创建唯一约束)。
- - 数据库列备注,并非所有数据库类型都支持。
- - 十进制(精确数字)列的精度(仅适用于十进制列),这是为值存储的最大位数。仅用于某些列类型。
- - 十进制(精确数字)列的比例(仅适用于十进制列),表示小数点右侧的位数,且不得大于精度。 仅用于某些列类型。
- - 将属性设置为数字列。 仅在 MySQL 中使用。 如果是,MySQL 会自动将属性添加到此列。
- - 将属性设置为数字列。 仅在 MySQL 中使用。
- - 定义列字符集。 并非所有数据库类型都支持。
- - 定义列排序规则。
- - 在列类型中使用,以指定允许的枚举值列表。 你也可以指定数组或指定枚举类。
- - 生成的列表达式。 仅在MySQL中使用。
- - 生成的列类型。 仅在MySQL中使用。
- -返回列类型。 以字符串或对象的形式返回值。 仅在Postgres>)中使用。
- - 用于可以是数组的 postgres 列类型(例如 int [])
- - 用于将任意类型的属性编组为数据库支持的类型。
注意:大多数列选项都是特定于 RDBMS 的,并且在中不可用。
你可以使用实体继承减少代码中的重复。
例如,你有, , 三个实体:
正如你所看到的,所有这些实体都有共同的列:,,。 为了减少重复并产生更好的抽象,我们可以为它们创建一个名为的基类:
来自父实体的所有列(relations,embeds 等)(父级也可以扩展其他实体)将在最终实体中继承和创建。
TypeORM 支持存储树结构的 Adjacency 列表和 Closure 表模式。
邻接列表是一个具有自引用的简单模型。 这种方法的好处是简单,缺点是你不能因为连接限制而立刻加载一个树实体。
例如:
closure 表以特殊方式在单独的表中存储父和子之间的关系。 它在读写方面都很有效。
要了解有关 closure 表的更多信息,请查看 this awesome presentation by Bill Karwin.
例如:
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/10004.html