棱镜计划_棱镜vs类型

棱镜计划

Working with databases is an unavoidable part of being a backend developer.

作为后端开发人员,使用数据库是不可避免的部分。

In particular, the server-side JavaScript ecosystem offers an endless number of libraries that aim to make this task less painful. Some of the most popular include:

特别是,服务器端JavaScript生态系统提供了无数个旨在减轻此任务痛苦的库。 一些最受欢迎的包括:

  • Sequelize (an object-relational mapper, or ORM, library)

    续集 (对象关系映射器或ORM库)

  • pg/mysql (JavaScript clients for interfacing with a specific database)

    pg / MySQL的 (用于与特定数据库接口JavaScript客户端)

  • Knex.js (a general-purpose query builder)

    Knex.js (通用查询生成器)

Each of these libraries has its strengths and weaknesses.

这些库中的每一个都有其优点和缺点。

Using a lower-level library like pg offers significant performance benefits at the cost of being challenging to maintain over time (as you’re writing raw SQL queries). Nonetheless, using these libraries can be confusing for new developers as they require a strong understanding of SQL.

使用像pg这样的低级库可以带来显着的性能优势,但代价是随着时间的推移难以维护(在编写原始SQL查询时)。 尽管如此,使用这些库可能会使新开发人员感到困惑,因为他们需要对SQL有深入的了解。

On the other end of the spectrum, ORMs like Sequelize offer convenient abstractions that often simplify working with databases. Nevertheless, they come at the cost of performance as the underlying SQL that is generated is generally less efficient than if an experienced programmer wrote it.

另一方面,Sequelize之类的ORM提供了方便的抽象,这些抽象通常简化了数据库的使用。 尽管如此,它们以性能为代价,因为所生成的基础SQL通常比有经验的程序员编写它的效率低。

Query builders like Knex.js aim to be less cumbersome and more efficient than ORMs, but more comfortable to use and maintain than raw SQL. Despite this goal, they still need a strong understanding of SQL to use in most cases.

像Knex.js这样的查询构建器的目标是比ORM少麻烦和高效,但比原始SQL更加易于使用和维护。 尽管有此目标,但他们仍然需要对SQL拥有深刻的理解,以便在大多数情况下使用。

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” — Martin Fowler

任何傻瓜都可以编写计算机可以理解的代码。 好的程序员编写人类可以理解的代码。” —马丁·福勒(Martin Fowler)

On the whole, there is no perfect tool for working with databases. However, the rising popularity of TypeScript with Node.js has led to the evolution of several libraries that aim to offer improved developer UX, simplified code, and acceptable performance. Two of these are Prisma and TypeORM.

总体而言,没有完美的工具来处理数据库。 但是,随着TypeScript与Node.js的日益普及,导致了一些库的发展,这些库旨在提供改进的开发人员UX,简化的代码和可接受的性能。 其中两个是PrismaTypeORM

In the following sections, we’ll take a look at a high-level overview for each tool, walk through some common developer scenarios, and evaluate each from a developer’s point of view.

在以下各节中,我们将查看每种工具的高级概述,逐步介绍一些常见的开发人员方案,并从开发人员的角度评估每种方案。

大图景 (The Big Picture)

棱镜概述 (Prisma Overview)

Note: In this article, we’ll be looking at Prisma 2.x. While Prisma is compatible with JavaScript, all the following examples will use TypeScript.

注意:在本文中,我们将研究Prisma2.x。 虽然Prisma与JavaScript兼容,但以下所有示例都将使用TypeScript。

One of the most common questions asked at first glance is, “is Prisma an ORM?” While it shares some characteristics with ORMs, an in-depth look at it indicates that it is different.

乍一看,最常见的问题之一是:“ Prisma是ORM吗? “虽然它与ORM具有某些特性,但深入研究表明它与众不同。

“ORMs are libraries that map tables in your database to classes in your programming language. Prisma, on the other hand, is a database toolkit. The toolkit includes Prisma Client, which is an auto-generated query builder that exposes queries which are tailored to your models. All Prisma Client queries return plain old JavaScript objects.” — Prisma Documentation

“ ORM是将数据库中的表映射到您的编程语言的类的库。 另一方面,Prisma是一个数据库工具包。 该工具包包含Prisma Client,Prisma Client是自动生成的查询构建器,它公开了针对您的模型量身定制的查询。 所有Prisma Client查询都返回普通的旧JavaScript对象。” — 棱镜文件

Breaking down the above quote, Prisma bills itself as a “database toolkit.” The three main components of this are:

分解上面的报价,Prisma称自己为“数据库工具箱”。 这三个主要组成部分是:

At the time of writing this, Prisma Migrate and Prisma Studio are still experimental. See the product roadmap here for details on development timelines.

在撰写本文时,Prisma Migrate和Prisma Studio仍处于试验阶段。 有关开发时间表的详细信息,请参见此处的产品路线图。

One of the significant differentiators between Prisma and an ORM is its centralized schema file and its schema language. Rather than having classes in your application the map to database entities, Prisma separates your database models from your code.

Prisma和ORM之间的主要区别之一是其集中式模式文件和其模式语言。 Prisma不会将应用程序中的类映射到数据库实体,而是将数据库模型与代码分开。

Furthermore, the Prisma CLI uses this schema file to autogenerate a client that can be used in your TypeScript code to interact with the database. This paradigm is slightly different than in an ORM, where instances of model classes fill this role.

此外,Prisma CLI使用此架构文件自动生成客户端,该客户端可在您的TypeScript代码中用于与数据库进行交互。 这种范例与ORM稍有不同,在ORM中,模型类的实例扮演着这个角色。

TypeORM概述 (TypeORM Overview)

NOTE: Code examples demonstrating TypeORM will use repositories, the query builder, and TypeScript (although vanilla JavaScript is supported).

注意:演示TypeORM的代码示例将使用存储库,查询生成器和TypeScript(尽管支持普通JavaScript)。

TypeORM is an open-source ORM for Node.js that takes advantage of modern JavaScript features and encourages the use of TypeScript. Looking at its syntax and structure, it’s clear that it derives inspiration from successful ORMs in other programming languages/frameworks such as Entity Framework (.NET) and Hibernate (Java).

TypeORM是Node.js的开源ORM,它利用了现代JavaScript功能并鼓励使用TypeScript。 从其语法和结构来看,很明显,它是从其他编程语言/框架(例如, 实体框架 (.NET)和Hibernate (Java))中成功的ORM中获得灵感的。

At a high level, TypeORM includes features such as migrations, transactions, a CLI, and a multitude of ways to interact with entities defined in your application’s data model. Entities are one of the core components of TypeORM and, like in other ORMs, they are classes that map to database tables.

从高层次上讲,TypeORM包括迁移,事务,CLI和与应用程序数据模型中定义的实体进行交互的多种方式等功能。 实体是TypeORM的核心组件之一,并且像在其他ORM中一样,它们是映射到数据库表的类。

One of the more powerful features of TypeORM is how you can work with entities in your code. Specifically, TypeORM supports both the Active Record and Data Mapper patterns.

TypeORM的更强大功能之一是如何在代码中使用实体。 具体来说,TypeORM支持活动记录模式和数据映射器模式。

At a high level, the Active Record pattern involves database functions (creating, reading, updating, deleting, etc.) being defined directly on a model class. For example, if we have a company class, then every class instance includes database functions like create in its method set. Likewise, TypeORM implements this as database operations defined on any entity class that extends the built-inBaseEntity class.

在较高级别上,Active Record模式涉及直接在模型类上定义的数据库功能(创建,读取,更新,删除等)。 例如,如果我们有一个公司类,则每个类实例在其方法集中都包含数据库函数,例如create 。 同样,TypeORM将此实现为在扩展内置BaseEntit y类的任何实体类上定义的数据库操作。

Looking now at the Data Mapper pattern, it is subtly different from the Active Record pattern. In particular, the Data Mapper pattern involves classes that are separate from your entities that define database functions (sometimes called data access objects). In this paradigm, entities are simple data structures that define their properties while the data mapper classes expose actual functionality needed to interact with a database. TypeORM provides two abstractions that allow you to apply this pattern, repositories and the entity manager. The fundamental difference between these two is that a repository only operates on a single entity type, i.e. having a CompanyRepository for a Company entity. In contrast, the entity manager is a collection of all repositories.

现在看一下Data Mapper模式,它与Active Record模式有细微的不同。 特别是,Data Mapper模式涉及与定义数据库功能的实体(有时称为数据访问对象 )不同的类。 在这种范例中,实体是定义其属性的简单数据结构,而数据映射器类则公开了与数据库交互所需的实际功能。 TypeORM提供了两种抽象,可用于应用此模式: 存储库实体管理器 。 两者之间的根本区别在于,存储库仅在单一实体类型上运行,即具有Company实体的CompanyRepository 。 相反,实体管理器是所有存储库的集合。

TypeORM offers another way to work with your database, referred to as the Query Builder. This feature integrates aspects of a query building library like Knex.js right into TypeORM. It is particularly helpful for complex queries that are more straightforward when approached using SQL than the API exposed by other TypeORM abstractions (repositories, entity manager, etc.). We’ll take a look at how to apply this tool effectively in later sections.

TypeORM提供了另一种使用数据库的方式,称为Query Builder 。 此功能将诸如Knex.js之类的查询构建库的各个方面直接集成到TypeORM中。 对于使用SQL进行查询的复杂查询,它比其他TypeORM抽象(存储库,实体管理器等)公开的API更为直接的复杂查询特别有用。 我们将在后面的部分中介绍如何有效地应用此工具。

With the overviews out of the way, let’s dive into some common developer scenarios using each technology with code-based examples.

在不进行概述的情况下,让我们使用每种技术和基于代码的示例来深入研究一些常见的开发人员场景。

NOTE: The complete/working source code for the following examples can be found here.

注意 :以下示例的完整/工作源代码可以在此处找到。

设置棱镜 (Setting Up Prisma)

To setup Prisma, we’ll need a few dependencies. Specifically, the Prisma Client and the Prisma CLI.

要设置Prisma,我们需要一些依赖项。 具体来说,是Prisma ClientPrisma CLI

Once these are in our package.json, we’ll also need a Prisma schema file as shown below:

一旦将它们放入我们的package.json ,我们还需要一个Prisma模式文件,如下所示:

An example Prisma schema file
Prisma模式文件示例

Here we see several Prisma constructs including generators, data sources, and models.

在这里,我们看到了几个Prisma构造,包括生成器,数据源和模型。

The generator block provides details about the client that will be created when we run the CLI prisma generate command. In this particular case, we’re specifying that we want to create a JavaScript client. Notably, Prisma also supports a Go client.

生成器块提供了有关在我们运行CLI prisma generate命令时将创建的客户端的详细信息。 在这种情况下,我们指定要创建一个JavaScript客户端。 值得注意的是,Prisma还支持Go客户端。

The data source block defines the database connection. In the above instance, we connect to a local Postgres instance with a URL provided by a .env file shown below:

数据来源 块定义数据库连接。 在以上实例中,我们使用由.env文件提供的URL连接到本地Postgres实例,如下所示:

A .env file defining a URL
定义URL的.env文件

The model block represents the tables that are a part of your application’s domain. We have three tables including Company, Product, and Customer. Using the Prisma Schema Language (PSL), we can concisely define relations between tables (one-to-many, many-to-many, etc.), primary keys, uniqueness constraints, and much more.

模型块代表作为应用程序域一部分的表。 我们有三个表,包括CompanyProductCustomer 。 使用Prisma Schema Language(PSL),我们可以简明地定义表之间的关系( 一对多多对多等),主键,唯一性约束等等。

In the case of the many-to-many relationship defined between product and customer, we do not need to declare a join table in our schema explicitly. For this, we use Prisma’s implicit many-to-many relation feature. This feature still creates a join table in the underlying database but allows us to abstract it from our code.

在产品和客户之间定义了多对多关系的情况下,我们不需要在架构中显式声明联接表。 为此,我们使用Prisma的隐式多对多关系功能。 此功能仍在基础数据库中创建联接表,但允许我们从代码中对其进行抽象。

For additional details and a deeper understanding of what’s possible in PSL, I encourage you to check out the official specification.

有关其他详细信息和对PSL功能的更深入的了解,我建议您查看官方规范

Finally, to use the Prisma client in our application code, we need to generate a client for our data model and apply the database schema. We do this via the CLI by running prisma generate and prisma migrate save --experimental && prisma migrate up --experimental.

最后,要在我们的应用程序代码中使用Prisma客户端,我们需要为我们的数据模型生成一个客户端并应用数据库模式。 我们通过以下命令通过CLI来执行此操作:运行prisma generateprisma migrate save --experimental && prisma migrate up --experimental

If all goes well, our application’s schema will have been applied to the local database, and a custom Prisma client will have been generated in our node_modules/@prisma/client directory.

如果一切顺利,我们的应用程序架构将被应用于本地数据库,并且将在我们的node_modules/@prisma/client目录中生成一个自定义Prisma客户node_modules/@prisma/client

设置类型ORM (Setting Up TypeORM)

To setup TypeORM, we also need to install a few dependencies. Notably, we’ll need the TypeORM package, reflect-metadata, and a database driver (in our case, pg).

要设置TypeORM,我们还需要安装一些依赖项。 值得注意的是,我们将需要TypeORM包reflect-metadata和数据库驱动程序(在我们的示例中为pg )。

Once these are in our package.json, we’ll need a configuration file like the one shown below:

一旦将它们放入我们的package.json ,我们将需要一个如下所示的配置文件:

Configuration file for TypeORM
TypeORM的配置文件

In the configuration file, we do a variety of things including:

在配置文件中,我们做了很多事情,包括:

  • Define connection details for our local Postgres database

    为我们的本地Postgres数据库定义连接详细信息
  • Set the synchronize option to true so that the data model between our application and database is aligned whenever we connect (this should be off in production)

    synchronize选项设置为true,以便在每次连接时对齐应用程序和数据库之间的数据模型(在生产中应该关闭)

  • Point to the location of our entities after they have been transpiled

    指向我们的实体被转换后的位置

Notably, TypeORM supports configuration file formats other than JSON. See here for more details.

值得注意的是,TypeORM支持除JSON之外的其他配置文件格式。 有关更多详细信息,请参见此处

The final step is to define entities that are part of our application’s domain. We’ll use the same ones as we did during the Prisma setup:

最后一步是定义属于我们应用程序域的实体。 我们将使用与设置Prisma时相同的方法:

Company entity
公司实体
Product entity
产品实体
Customer entity
客户实体

In the above models, we create the same columns, relations, and constraints as we did previously. To define all of these, TypeORM takes advantage of TypeScript decorators. The result of this is a clean syntax that is easy to read and comprehend. For a complete list of TypeORM decorators, see here.

在上述模型中,我们创建的列,关系和约束与之前相同。 为了定义所有这些,TypeORM利用了TypeScript 装饰器 。 这样的结果是易于阅读和理解的简洁语法。 有关TypeORM装饰器的完整列表,请参见此处

创造 (Create)

棱镜 (Prisma)

To begin, we’ll insert a company below:

首先,我们将在下面插入一家公司:

Creating a company (Prisma)
创建公司(Prisma)

Prisma’s syntax will immediately feel familiar to developers who are comfortable with GraphQL. In the above, we use the create function to insert a new database record. We do this by providing the fields necessary to create a new company in the data field (only the name property is required).

熟悉GraphQL的开发人员将立即感到Prisma的语法。 在上面,我们使用create函数来插入新的数据库记录。 为此,我们在data字段中提供了创建新公司所需的字段(仅name属性是必需的)。

As a side note, one of the cool features of Prisma is that it also generates robust TypeScript types:

附带说明一下,Prisma的一项很酷的功能是它还会生成健壮的TypeScript类型:

One of the autogenerated types for the Company entity
公司实体的自动生成类型之一

The result of this is an intuitive developer UX that makes it straightforward to understand the API of our custom Prisma client.

这样的结果是直观的开发人员UX,使您可以直接了解自定义Prisma客户端的API。

Moving on, let’s look at more complex use cases involving relations:

继续,让我们看一下涉及关系的更复杂的用例:

Creating a product and linking it to a company (Prisma)
创建产品并将其链接到公司(Prisma)
Creating a customer and linking it to several products (Prisma)
创建客户并将其链接到多个产品(Prisma)

In the above, we have done several things including:

在上面,我们做了几件事,包括:

  • Created a new product and customer in our database

    在我们的数据库中创建了新产品和客户
  • Connected a new product to an existing company via the company’s name field (a many-to-one/one-to-many relationship)

    通过公司name字段将新产品连接到现有公司(多对一/一对多关系)

  • Linked a new customer to several existing products via their name fields (a many-to-many relationship)

    通过其name字段将新客户链接到几个现有产品(多对多关系)

Another cool feature provided by Prisma is the ability to perform nested writes for entities with relations. This translates to the ability to create several related entities at one time, all while operating as a transaction:

Prisma提供的另一个很酷的功能是能够对具有关系的实体执行嵌套写入 。 这意味着可以一次创建多个相关实体,而所有这些实体都是作为事务操作的:

An example of nested writes (Prisma)
嵌套写入的示例(Prisma)

类型ORM (TypeORM)

Now let’s do the same series of create operations, but with TypeORM. Once again, we’ll create a company with the same properties:

现在,让我们执行相同系列的创建操作,但使用TypeORM。 再一次,我们将创建一个具有相同属性的公司:

Creating a company (TypeORM)
创建公司(TypeORM)

Using the repository pattern, we retrieve a repository-specific to one of our database models and use it to create an instance of that model with the create method. We then persist it to the database by calling save.

使用存储库模式,我们检索特定于我们数据库模型之一的存储库,并使用它通过create方法create该模型的实例。 然后,我们通过调用save其持久化到数据库中。

Now let’s look at some more complex create examples using the product and customer entities:

现在,让我们来看一些使用产品和客户实体的更复杂的创建示例:

Creating a product and linking it to a company (TypeORM)
创建产品并将其链接到公司(TypeORM)

In the case of creating a new product, we need both the ProductRepository and the CompanyRepository.

在创建新产品的情况下,我们同时需要ProductRepositoryCompanyRepository

The CompanyRepository is used to find the company associated with the product in the database. A new product is then created using the ProductRepository, including its foreign key relation to the company entity.

CompanyRepository用于在数据库中查找与产品关联的公司。 然后使用ProductRepository创建一个新产品,包括它与公司实体的外键关系。

We again persist the product to the database with the save operation.

我们再次通过save操作将产品持久化到数据库中。

Creating a customer and linking it to several products (TypeORM)
创建客户并将其链接到多个产品(TypeORM)

Similarly to the previous example, we use multiple repositories to create a new customer. In the above, we find all the products that a customer consumes, create a new customer (including foreign keys), and finally save the new customer.

与前面的示例类似,我们使用多个存储库来创建新客户。 在上面,我们找到了客户消费的所有产品,创建了一个新客户(包括外键),最后保存了该新客户。

(Read)

棱镜 (Prisma)

Starting with a simple example, finding a single company by name looks like this:

从一个简单的示例开始,按名称查找单个公司如下所示:

Find a company by name (Prisma)
按名称查找公司(Prisma)

This should make sense given the syntax we’ve already seen and uses a filter condition to find a company by a specific field.

鉴于我们已经看到的语法,这应该是有道理的,并使用过滤条件按特定字段查找公司。

Now onto a more complex example. For example, what if we wanted to find all the customers who consume the products of a specific company?

现在来看一个更复杂的例子。 例如,如果我们想找到所有消费特定公司产品的客户该怎么办?

Find the usernames of a company’s customers (Prisma)
查找公司客户的用户名(Prisma)

In the above, we take advantage of field selection and sorting. Specifically, we’re only returning the username field of the relevant customers in descending order.

在上面,我们利用了字段选择排序的优势。 具体来说,我们仅以降序返回相关客户的username名字段。

Also, the use of the some operator indicates that we are looking for products where one or more records match the criteria provided (at least one of the products needs to be related to a company with the name of “Acme”).

同样,使用some运算符表示我们正在寻找一种或多种记录与提供的条件相匹配的产品(至少一种产品需要与名为“ Acme”的公司相关)。

This query could also be achieved from the opposite side of the relation (querying starting with the Company and using its side of the relationship).

该查询也可以从关系的另一侧来实现(从Company开始并使用其关系的另一侧进行查询)。

As a final example, Prisma also supports the use of multiple filter conditions:

作为最后一个示例,Prisma还支持使用多个过滤条件

Find companies that make cars or dynamite (Prisma)
查找制造汽车或炸药的公司(Prisma)

类型ORM (TypeORM)

We’ll start by finding a company by name:

我们将从找到一家公司开始:

Find a company by name (TypeORM)
按名称查找公司(TypeORM)

In the above, we use the CompanyRepository and its findOne method to retrieve a single company based on a condition (in this case the name property).

上面,我们使用CompanyRepository及其findOne方法根据条件(在本例中为name属性)检索单个公司。

Looking at the next case, let’s find all the customers of a specific company:

查看下一个案例,让我们找到特定公司的所有客户:

Find the usernames of a company’s customers (TypeORM)
查找公司客户的用户名(TypeORM)

Here’s where it gets a little more interesting with TypeORM.

这就是使用TypeORM变得更有趣的地方。

We’re attempting to perform more than just a basic find operation in the above query. Given this, it makes sense to take advantage of TypeORM’s query builder (as performing the same operation using the repository API is cumbersome).

在上述查询中,我们尝试执行的不仅仅是基本的查找操作。 鉴于此,利用TypeORM的查询构建器是有意义的(因为使用存储库API执行相同的操作很麻烦)。

As mentioned before, the query builder is a TypeORM feature that allows you to build and execute SQL queries with an intuitive API.

如前所述,查询构建器是TypeORM功能,允许您使用直观的API构建和执行SQL查询。

Using theCustomerRepository, we first create a query builder instance for the customer table. We then perform join operations to select all of the companies related to the products that our customers consume, before filtering down to the ones that match a specific condition (the company name property). Finally, we select only the username and order the output in descending order.

使用CustomerRepository ,我们首先为customer表创建查询构建器实例。 然后,我们执行联接操作以选择与客户消费的产品相关的所有公司,然后筛选出符合特定条件的公司(公司name属性)。 最后,我们仅选择用户名,并按降序对输出进行排序。

As another application of the query builder, below is an example of how we could find all the companies that make a specific set of products:

作为查询生成器的另一个应用程序,下面是一个示例,说明如何查找所有制造特定产品集的公司:

Find companies that make cars or dynamite (TypeORM)
查找制造汽车或炸药的公司(TypeORM)

更新资料 (Update)

棱镜 (Prisma)

Updating a database record with Prisma uses a syntax similar to the create and read examples. Updating a product description is shown below:

使用Prisma更新数据库记录时使用的语法类似于create和read示例。 更新产品说明如下所示:

Update product description (Prisma)
更新产品说明(Prisma)

Here we provide a search condition in the where field (the name property), and then include the field(s) to update in the data property (the description property).

在这里,我们在where字段( name属性)中提供搜索条件,然后在data属性( description属性)中包括要更新的字段。

类型ORM (TypeORM)

Using the same example as above, updating a product description in TypeORM is shown below.

使用与上述相同的示例,下面显示了更新TypeORM中的产品说明。

Update product description (TypeORM)
更新产品说明(TypeORM)

Since this is a relatively simple query, we use the update function on the ProductRepository. This function takes two objects, the first being the search condition(s) and the second being the field(s)/value(s) to update.

由于这是一个相对简单的查询,因此我们在ProductRepository上使用update函数。 该函数有两个对象,第一个是搜索条件,第二个是要更新的字段/值。

删除 (Delete)

棱镜 (Prisma)

The next common developer scenario we’ll look at with Prisma is deleting a database entry. For example, removing a customer by a specific filter condition is shown below:

我们将在Prisma中看到的下一个常见开发人员场景是删除数据库条目。 例如,下面显示了通过特定过滤条件移除客户:

Delete customer by username (Prisma)
按用户名删除客户(Prisma)

The delete operation supports the same filtering capability of the findOne and findMany operations illustrated in the previous section.

delete操作支持与上一节中说明的findOnefindMany操作相同的过滤功能。

Additionally, the delete operation only deletes a single database entry. For batch deletes, use deleteMany.

此外, delete操作仅删除单个数据库条目。 对于批量删除,请使用deleteMany

类型ORM (TypeORM)

Deleting a customer by username is shown below:

按用户名删除客户如下所示:

Delete customer by username (TypeORM)
通过用户名删除客户(TypeORM)

The delete operation on the CustomerRepository takes in an object with search condition(s) as a parameter, and can be used to delete one or more database entries.

CustomerRepository上的delete操作将一个对象以搜索条件作为参数,并且可用于删除一个或多个数据库条目。

交易次数 (Transactions)

棱镜 (Prisma)

We’ve already shown one way to perform transactions using Prisma. Specifically, whenever you create related entities as part of a nested write, there is a transactional guarantee (meaning the operation succeeds or fails as a single unit).

我们已经展示了一种使用Prisma进行交易的方法。 具体来说,每当您将相关实体创建为嵌套write的一部分时,就存在事务保证(意味着该操作作为一个单元成功或失败)。

However, there is one additional way to perform transactions. It uses the experimental transaction API as illustrated:

但是,还有另一种执行事务的方法。 它使用实验性交易API,如下所示:

Transaction API (Prisma)
交易API(Prisma)

In the above, we create a company and customer as part of the same transaction. This is useful when unrelated entities need transactional guarantees, though this feature is not ready for production at the time of writing.

在上面,我们创建了公司和客户作为同一笔交易的一部分。 当不相关的实体需要交易担保时,这很有用,尽管在撰写本文时此功能尚未准备好用于生产。

类型ORM (TypeORM)

TypeORM also provides an API for performing transactions as shown:

TypeORM还提供用于执行事务的API,如下所示:

Transaction API (TypeORM)
交易API(TypeORM)

A transaction in TypeORM relies on the transaction method on the entity manager. In turn, this method takes a function as a parameter that provides a new entity manager that must be used for all operations in the transaction.

TypeORM中的transaction依赖于实体管理器上的transaction方法。 反过来,此方法将函数用作参数,该参数提供必须用于事务中所有操作的新实体管理器。

In the above, we create a company and user using the entity manager specific to the transaction.

在上面,我们使用特定于交易的实体管理器来创建公司和用户。

原始SQL (Raw SQL)

棱镜 (Prisma)

Prisma offers the capability to perform queries using raw SQL, as shown below:

Prisma提供了使用原始SQL执行查询的功能,如下所示:

Raw SQL (Prisma)
原始SQL(Prisma)

One of the drawbacks of this approach is that you lose the type safety from the Prisma client’s autogenerated types. Nonetheless, writing SQL queries can occasionally be necessary, and you can write custom type definitions to restore type safety.

这种方法的缺点之一是您将失去Prisma客户端自动生成的类型的类型安全性。 但是,有时可能需要编写SQL查询,并且您可以编写自定义类型定义以恢复类型安全。

类型ORM (TypeORM)

Likewise, TypeORM can perform raw SQL queries:

同样,TypeORM可以执行原始SQL查询:

Raw SQL (TypeORM)
原始SQL(TypeORM)

For the most part, the query builder feature can be used to avoid writing raw SQL (though it is still convenient to have the option).

在大多数情况下,查询生成器功能可用于避免编写原始SQL(尽管使用该选项仍然很方便)。

评价 (Evaluation)

棱镜 (Prisma)

After working with Prisma, my impression is that it has a ton of potential. Working with it from a developer perspective was exceptionally straightforward, especially compared to other popular database tools like Sequelize.

与Prisma合作之后,我的印象是它具有巨大的潜力。 从开发人员的角度来看,使用它非常简单,特别是与Sequelize等其他流行的数据库工具相比

Additionally, the Prisma documentation made it painless to get an example up and running quickly. The only hiccup I encountered while working with it was using the implicit many-to-many feature. Specifically, it took several tries to get the table naming conventions correct and working with the Prisma CLI’s introspection feature (this converts an existing database schema to a Prisma schema file).

此外,Prisma 文档使创建示例和快速运行变得毫不费力。 我在使用它时遇到的唯一麻烦是使用隐式多对多功能。 具体来说,它花了几次尝试才能使表命名约定正确并与Prisma CLI的自省功能一起使用(这会将现有的数据库模式转换为Prisma模式文件)。

While the limitations and requirements for this feature are well documented, this could be difficult to use in a production environment and require a workaround.

尽管对此功能的限制和要求已得到充分记录 ,但在生产环境中可能很难使用它,并且需要解决方法。

While Prisma still has a long way to go, it has made tremendous progress and has the possibility of becoming a go-to database tool with Node.js and TypeScript.

尽管Prisma还有很长的路要走,但它已经取得了巨大的进步,并有可能成为Node.js和TypeScript的首选数据库工具。

Pros

优点

  • Easy to use and intuitive syntax

    易于使用和直观的语法
  • Great in a stack that leverages GraphQL

    充分利用GraphQL的堆栈
  • Amazing TypeScript support

    出色的TypeScript支持
  • Prisma Schema Language (PSL) is both straightforward and powerful

    Prisma Schema Language(PSL)既简单又强大
  • Backed by a team of dedicated developers and venture capital funding

    由一群敬业的开发商和风险投资基金支持

Cons

缺点

  • Still has a ways to go, lots of features still under development

    仍有路要走,许多功能仍在开发中
  • Migrations feature (Prisma Migrate) still experimental

    迁移功能( Prisma Migrate )仍处于实验阶段

  • No long-running transactions

    没有长期交易
  • No access to the underlying database connection

    无法访问基础数据库连接
  • The implicit many-to-many relation feature is a little bit brittle

    隐含的多对多关系特征有些脆弱

类型ORM (TypeORM)

Having used TypeORM on more than a few projects, I’ve always found it to be a powerful database tool that covered everyday use cases. Notably, the query builder always comes in handy for more difficult queries that would be challenging to implement with other ORMs.

在多个项目上使用TypeORM之后,我一直发现它是一个功能强大的数据库工具,涵盖了日常使用案例。 值得注意的是,查询构建器总是可以方便地处理更困难的查询,而这些查询对于使用其他ORM实施将具有挑战性。

Furthermore, TypeORM uses TypeScript decorators extremely effectively. The result of this is entity classes that are expressive and easy to read.

此外,TypeORM非常有效地使用TypeScript装饰器。 这样的结果是具有表现力且易于阅读的实体类。

TypeORM also continues to be popular among developers, with the package receiving more than 350k weekly downloads on NPM at the time of writing. However, the major drawback to TypeORM is that it has many outstanding issues on Github and an equal number of known bugs.

TypeORM仍然继续受到开发人员的欢迎,在撰写本文时,该软件包每周在NPM上收到超过35万次下载 。 但是,TypeORM的主要缺点是在Github上存在许多突出的问题,并且存在相同数量的已知错误。

Due to the fact that the project doesn’t have a staff of full-time developers like Prisma, support, and fixes for known issues are relatively slow. This could lead to diminished popularity for TypeORM over time, as well as limit enterprise adoption.

由于该项目没有像Prisma这样的专职开发人员,因此对已知问题的支持和修复相对较慢。 随着时间的流逝,这可能会导致TypeORM的受欢迎程度下降,并限制企业的采用。

Pros

优点

  • Works well with both TypeScript and JavaScript

    与TypeScript和JavaScript均能很好地工作
  • Tons of features, and supports a wide variety of relational databases

    众多功能,并支持各种关系数据库
  • Query builder feature adds flexibility and power when it counts

    查询构建器功能很重要,可以增加灵活性和功能
  • Uses decorators effectively

    有效地使用装饰器
  • Migrations feature work well/is more mature than Prisma’s

    迁移功能运行良好/比Prisma的成熟

Cons

缺点

  • Lots of bugs and open issues

    很多错误和未解决的问题

  • Documentation isn’t great for advanced use cases

    文档不适用于高级用例

  • Subpar support from Github maintainers

    Github维护者的支持不足

  • Not mature/well-supported enough for enterprise adoption

    尚不成熟/缺乏足够的支持,无法被企业采用
  • Not backed by significant funding

    没有大量资金支持

总结思想 (Closing Thoughts)

Both TypeORM and Prisma offer an excellent developer UX and feature set. In the short term, I foresee TypeORM remaining more popular than Prisma. This is because TypeORM already has a significant lead in popularity over Prisma and an edge in terms of maturity (for example, migrations).

TypeORM和Prisma都提供了出色的开发人员UX和功能集。 在短期内,我预计TypeORM仍然比Prisma更受欢迎。 这是因为TypeORM在Prisma方面已经具有明显的领先优势,并且在成熟度(例如迁移)方面具有优势。

In the long term, Prisma has the distinct possibility of overtaking TypeORM given its strong financial backing and core group of full-time developers working on building out features. Moreover, TypeORM will likely be weighed down by open Github issues/bugs and lack of full-time maintainer support.

从长远来看,Prisma拥有强大的财务支持和致力于构建功能的核心全职开发人员团队,因此有可能超越TypeORM。 而且,由于开放的Github问题/错误以及缺乏全职维护人员的支持,TypeORM可能会受到影响。

Regardless of the outcome, both tools offer significant promise and it will be exciting to see how they develop over time.

不管结果如何,这两种工具都可以提供很大的希望,并且随着时间的推移它们将如何发展将令人兴奋。

As always, I would love to hear any thoughts about Prisma/TypeORM, where they fit into the Node.js ecosystem, and real-world use cases! Until next time, thanks for reading.

与往常一样,我很想听听有关Prisma / TypeORM的任何想法,它们适合于Node.js生态系统,以及实际的用例! 直到下一次,谢谢您的阅读。

翻译自: https://medium.com/better-programming/prisma-vs-typeorm-60d02f9dac64

棱镜计划

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值