ORM(Object relational mappers) 的含义是,将数据模型与 Object 建立强力的映射关系,这样我们对数据的增删改查可以转换为操作 Object(对象)。
Prisma 是一个现代 Nodejs ORM 库,根据 Prisma 官方文档 可以了解这个库是如何设计与使用的。
概述
Prisma 提供了大量工具,包括 Prisma Schema、Prisma Client、Prisma Migrate、Prisma CLI、Prisma Studio 等,其中最核心的两个是 Prisma Schema 与 Prisma Client,分别是描述应用数据模型与 Node 操作 API。
与一般 ORM 完全由 Class 描述数据模型不同,Primsa 采用了一个全新语法 Primsa Schema 描述数据模型,再执行 prisma generate
产生一个配置文件存储在 node_modules/.prisma/client
中,Node 代码里就可以使用 Prisma Client 对数据增删改查了。
Prisma Schema
Primsa Schema 是在最大程度贴近数据库结构描述的基础上,对关联关系进行了进一步抽象,并且背后维护了与数据模型的对应关系,下图很好的说明了这一点:
可以看到,几乎与数据库的定义一模一样,唯一多出来的 posts
与 author
其实是弥补了数据库表关联外键中不直观的部分,将这些外键转化为实体对象,让操作时感受不到外键或者多表的存在,在具体操作时再转化为 join 操作。下面是对应的 Prisma Schema:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model Post {
id Int @id @default(autoincrement())
title String
content String? @map("post_content")
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
datasource db
申明了链接数据库信息;generator client
申明了使用 Prisma Client 进行客户端操作,也就是说 Prisma Client 其实是可以替换实现的;model
是最核心的模型定义。
在模型定义中,可以通过 @map
修改字段名映射、@@map
修改表名映射,默认情况下,字段名与 key 名相同:
model Comment {
title @map("comment_title")
@@map("comments")
}
字段由下面四种描述组成:
字段名。
字段类型。
可选的类型修饰。
可选的属性描述。
model Tag {
name String? @id
}
在这个描述里,包含字段名 name
、字段类型 String
、类型修饰 ?
、属性描述 @id
。
字段类型
字段类型可以是 model,比如关联类型字段场景:
model Post {
id Int @id @default(autoincrement())
// Other fields
comments Comment[] // A post can have many comments
}
model Comment {
id Int
// Other fields
Post Post? @relation(fields: [postId], references: [id]) // A comment can have one post
postId Int?
}
关联场景有 1v1, nv1, 1vn, nvn 四种情况,字段类型可以为定义的 model 名称,并使用属性描述 @relation
定义关联关系,比如上面的例子,描述了 Commenct
与 Post
存在 nv1 关系,并且 Comment.postId
与 Post.id
关联。
字段类型还可以是底层数据类型,通过 @db.
描述,比如: