前言

prisma出了2个大版本,两者不大相同,这里只讲prisma2。 由于之前prisma1集成比较高,导致我把prisma理解为一个graphql服务框架,是错误的。**Prisma是一种数据库工具包,可简化数据库访问,Prisma Client仅“负责”向数据库发送查询。**因此可以将其与您选择的任何HTTP服务器库或Web框架结合使用。您可以使用Prisma工具构建GraphQL或REST API,或者作为全栈应用程序的一部分-结合Prisma的程度取决于您。

  1. restful prisma可以和http服务框架结合生成restful框架
  2. graphql 使用Prisma,您可以构建连接到数据库的GraphQL服务器。 Prisma与您使用的GraphQL工具完全无关。nexus 是一个集成了prisma框架的GraphQL应用程序框架。
    Prisma Labs团队是Prisma工程团队其他成员的独立组成部分,致力于开发与Prisma数据库工具不直接相关的开源工具。Prisma Labs目前致力于将大部分时间用于Nexus,以期使其成为构建GraphQL服务器的成熟后端框架。也是本文下面要讲的部分。

prisma2.0

1 什么是prisma

prisma官网:https://www.prisma.io/

prisma是一个开源的数据库工具包。它取代了传统的ORM,并使用针对TypeScript和Node.js的自动生成的查询生成器使数据库访问变得容易。

prisma包括3个部分:

  1. prisma client:自动生成的类型安全的Node.js和TypeScript查询构建器
  2. prisma migrate:声明式数据建模和迁移系统
  3. prisma studio:GUI查看和编辑数据库中的数据

2 工作原理

每个使用prisma的项目都以一个prisma.schema文件开始。prisma.schema文件它以一直直观的数据建模语句定义应用程序模型,还包括了数据库连接和定义了一个生成器。数据模型表示基础数据库中的表,为Prisma Client API中的查询提供基础。
下面是一个prisma schema文件例子

datasource db {provider = "postgresql"url      = env("DATABASE_URL")
}  //这里定义了数据源,指定了数据库如何连接,可以通过环境变量,它会自动从和这个文件同名的.env文件中自动读取环境变量
generator client {provider = "prisma-client-js"
} // 这里表示要生成一个prisma client// 下面的数据模型 data model
model Post {id        Int     @id @default(autoincrement())title     Stringcontent   String?published Boolean @default(false)author    User?   @relation(fields:  [authorId], references: [id])authorId  Int?
}
model User {id    Int     @id @default(autoincrement())email String  @uniquename  String?posts Post[]
}

定义数据模型后,您可以生成Prisma Client,它将公开CRUD和已定义模型的查询。可以通过命令安装npm install @prisma/client 然后通过prisma generate生成prisma client 的代码,在.prisma/client文件夹,这里包括了自动生成的prisma client 。如果你改了data model ,需要收到运行generate命令,然后prisma client会自动更新。
Prisma Client生成后,您可以导入代码并将查询发送到数据库。代码大致如下:

import {PrismaClient} from '@prisma/client'const prisma = new PrismaClient()// A `main` function so that you can use async/await
async function main() {// ... you will write your Prisma Client queries here// createconst post = await prisma.post.create({data: {title: "Prisma makes databases easy",author: {connect: {email: "maria@prisma.io"},}}})const user = await prisma.user.create({data: {name: "Nancy1",email: "nancy1@prisma.io",Post: {create: {title: "Join us for Prisma Day 2020"}}}})// updateconst post = await prisma.post.update({where: {id: 2},data: {published: true}})// deleteconst deleteUser = await prisma.user.delete({where: {email: "sarah@prisma.io"}})// get listconst allUsers = await prisma.user.findMany({include: {Post: true}})// find oneconst user = await prisma.user.findOne({where: {email: "sarah@prisma.io"}}).posts()// filterconst filteredPosts = await prisma.post.findMany({where: {OR: [{title: {contains: "prisma"}},{content: {contains: "prisma"}}]}})
}

prisma 工作流有如下两种:
(1) SQL migrations and introspection :

  1. 使用SQL手动调整数据库架构
  2. 利用命令 prisma introspect去更新你的prisma schema 文件的data model
  3. 再利用prisma generate去更新生产你的prisma client
  4. 最后使用prisma client 在代码里去访问数据库
    (2) Prisma Migrate:
  5. 人工调整你的prisma schema data model
  6. 利用 prisma migrate save --experimental 生产/prisma/migratons文件
  7. prisma migrate up --experimental 命令去更新你的数据库
  8. 再利用prisma generate去更新生产你的prisma client
  9. 最后使用prisma client 在代码里去访问数据库

    Prisma引擎是数据库的直接接口,任何更高级别的接口始终通过引擎层与数据库通信。

3 核心概念

3.1 prisma schema

prisma schem 包括3个部分:

  1. Data source 定义了数据源,下面是几个常见数据源的几个定义方式
datasource postgresql {provider = "postgresql"url      = "postgresql://johndoe:mypassword@localhost:5432/mydb?schema=public"
}datasource mysql {provider = "mysql"url      = "mysql://johndoe:mypassword@localhost:5432/mydb"
}datasource sqlite {provider = "sqlite"url      = "file:./dev.db"
}

可以使用环境变量 通过创建具有以下内容的.env文件。请注意,该文件必须与schema.prisma文件位于同一目录中,以自动选择Prisma CLI。

datasource postgresql {provider = "postgresql"url      = env("DATABASE_URL")
}
  1. Generators
generator client {provider      = "prisma-client-js"  //描述要使用的生成器。这可以指向实现生成器的文件,也可以直接指定内置生成器output        = "node_modules/@prisma/client" // 确定生成的客户端的位置,了解更多信息。默认值:node_modules / @ prisma / clientbinaryTargets = ["native"] // 指定将在其上运行Prisma Client的操作系统,以确保查询引擎的二进制兼容性。默认值:本机
}
  1. Data model
    数据模型定义定义您的应用程序模型(也称为Prisma模型)。这些模型代表您的应用程序域的实体,并映射到数据库中的表。
  • model vs enum
enum Role {USERADMIN
}
model User {id    Int   @id @default(autoincrement())role  Role  @default(USER)
}

model 属性

name 数据库表示的含义 描述 例子
@id primary key 在模型上定义一个单字段ID id Int @id
@@id primary key 在模型上定义多个单字段ID @@id([title, author]))
@default default 定义此字段的默认值。 @default将表达式作为参数。 role Boolean @default(false)
@unique unique 为该字段定义唯一约束。 email String @unique
@@unique unique 为指定字段定义复合唯一约束。 @@unique([title, author])
@@index Index 字段引用列表定义索引 @@index([title, author])
@relation FOREIGN KEY / REFERENCES 定义有关关系的元信息 author User @relation(fields: [authorId], references: [id])
@map 将字段名称从Prisma模式映射到其他列名称 @map(_ name: String)
@@map 将字段名称从Prisma模式映射到其他列名称 @@map(_ name: String)
@updatedAt 自动存储上次更新记录的时间 createdAt DateTime @update
autoincrement() Id自增 id Int @id @default(autoincrement())
cuid() 根据cuid规范生成全局唯一标识符 id String @id @default(cuid())
uuid() 根据UUID规范生成全局唯一的标识符 id String @id @default(uuid())
new() 设置创建记录的时间的时间戳
dbgenerated() 表示无法在Prisma模式中表示的默认值。内省后才可用
  • Scalar types 表量类型: String Boolean Int Float DateTime(2020-03-19T14:21:00+0200) Json
  • 类型修饰符 []:将字段设为列表 ?:将字段设为可选 请注意,您不能在同一字段上组合列表和可选修饰符
  • relations关系
    (1)一对一
model User {id      Int      @id @default(autoincrement())profile Profile?
}
model Profile {id      Int     @id @default(autoincrement())user    User    @relation(fields: [userId], references: [id])userId  Int     // relation scalar field (used in the `@relation` attribute above)
}

(2)一对多

 model User {id        Int      @id @default(autoincrement())email     String   @uniquerole      Role     @default(USER)posts     Post[]
}
model Post {id         Int     @id @default(autoincrement())title      Stringauthor     User    @relation(fields: [authorId], references: [id])authorId   Int     // relation scalar field (used in the `@relation` attribute above)
}

(3)多对多
显式的多对多关系

model Post {id         Int                 @id @default(autoincrement())title      Stringcategories CategoriesOnPosts[]
}
model Category {id    Int                 @id @default(autoincrement())name  Stringposts CategoriesOnPosts[]
}
model CategoriesOnPosts {post        Post     @relation(fields: [postId], references: [id])postId      Int       // relation scalar field (used in the `@relation` attribute above)category    Category @relation(fields: [categoryId], references: [id])categoryId  Int      // relation scalar field (used in the `@relation` attribute above)@@id([postId, categoryId])
}

隐式的多对多关系

model Post {id         Int         @id @default(autoincrement())categories Category[]  @relation(references: [id])
}
model Category {id    Int     @id @default(autoincrement())posts Post[]  @relation(references: [id])
}

3.2 prisma client

Prisma Client为多个CRUD查询提供了开箱即用的支持。 CRUD代表:Creat read update Delete
Prisma Client中提供以下CRUD查询:

  • findOne ——findOne查询使您可以按ID或另一个唯一属性检索单个数据库记录。您可以使用select和include选项来确定应在返回的对象上包括哪些属性。select 和include不能同时存在,两者都是规定返回值。
 const user = await prisma.user.findOne({where: {email: "nancy1@prisma.io"},select: {id: true, email: true,Post:true},// include: {Post: true}})
  • findMany ——findMany查询返回记录列表。您可以使用select和include选项来确定返回的对象应包括哪些属性。您还可以对列表进行分页,过滤和排序。
    (1)where 查询
const user = await prisma.user.findMany({where: { name: 'Alice' },select: {id: true, email: true,Post:true},// include: {Post: true}
})

(2) 过滤

// AND OR NOT 结合多个过滤条件
// 过滤条件  euqals not in notin It(<) Ite(<=) gt(>) gte(>=) contains startsWith endsWith
const result = await prisma.post.findMany({where: {OR: [{title: {contains: 'Prisma',},}],NOT: {title: {contains: 'SQL',},},},
})
// Prisma Client提供以下运算符,用于筛选一对多关系: some every none
const result = await prisma.user.findMany({where: {post: {every: {published: true}some: {content: {contains: "Prisma"}}}}}// 用include filter
const result = await prisma.user.findMany({where: {email: {contains: 'prisma.io',},},include: {Post: {where: {published: false,},},},
})
// 用select filter
const result = await prisma.user.findMany({where: {email: {contains: 'prisma.io',},},select: {Post: {where: {published: false,},select: {title: true,},},},
})
  • create :创建查询将创建一个新的数据库记录。您可以使用select和include选项来确定应在返回的对象上包括哪些属性 data include select
const user = await prisma.user.create({data: {name: "Nancy1",email: "nancy1@prisma.io",Post: {create: {title: "Join us for Prisma Day 2020"}// connect: {id: 1},}}})
  • update:更新查询更新现有的数据库记录。您可以使用select和include选项来确定应在返回的对象上包括哪些属性。data where select include
const user = await prisma.user.update({where: { id: 1 },data: { email: 'alice@prisma.io' },
})
  • updateMany: updateMany查询批量更新一批现有数据库记录,并返回已删除记录的数量。您可以过滤要更新的记录列表 data where
const updatedUserCount = await prisma.user.updateMany({where: { name: 'Alice' },data: { name: 'ALICE' },
})
  • upsert:upsert查询更新现有记录或创建新的数据库记录。您可以使用select和include选项来确定应在返回的对象上包括哪些属性。 create update where select include
const user = await prisma.user.upsert({where: { id: 1 },update: { email: 'alice@prisma.io' },create: { email: 'alice@prisma.io' },
})
  • delete:删除查询删除现有的数据库记录。即使删除记录,删除仍然返回已删除的对象。您可以使用select和include选项来确定应在返回的对象上包括哪些属性。 where select include
const user = await prisma.user.delete({where: { id: 1 },
})
  • deleteMany:deleteMany查询将批量删除一批现有的数据库记录,并返回已删除记录的数量。您可以过滤要删除的记录列表。 where
const deletedUserCount = await prisma.user.deleteMany({where: { name: 'Alice' },
})
  • count:在PrismaClient实例上的任何模型属性上使用count()方法可返回一定数量的可用记录。您可以过滤要计数的记录列表。
const result = await prisma.user.count({where: {post: {some: {published: true,},},},
})
  • raw 原生数据查询
const result = await prisma.raw('SELECT * FROM User;')
  • connect() disconnect() 连接数据库和断开
const prisma = new PrismaClient()
await prisma.connect()
main().catch(e => {throw e}).finally(async () => {await prisma.disconnect()})
  • logging 您可以通过在PrismaClient构造函数中配置不同的日志级别来查看Prisma Client发送到数据库的生成的数据库查询以及警告和其他信息。您可以通过log选项执行此操作:
const prisma = new PrismaClient({log: ['query', 'info', 'warn'],
});
// query:记录由Prisma Client API调用生成的SQL查询
// info:记录常规信息
// 警告:记录警告
  • debug 您可以通过DEBUG环境变量在Prisma Client中启用调试输出。它接受两个名称空间来打印调试输出:export DEBUG="prisma-client,engine"
  • errorFormat 定义错误格式 minimal colorless pretty(默认)

3.3 prisma migrate

Prisma Migrate是一种工具,可让您更改数据库架构,例如通过创建新表或向现有表添加列。这些更改称为架构迁移。 Prisma Migrate可通过prisma migration命令作为Prisma CLI的一部分使用。

3.4 prisma instrospection

您可以使用Prisma CLI自检数据库,以便在Prisma模式中生成数据模型。需要数据模型来生成Prisma Client。用反映当前数据库模式的数据模型填充Prisma schema。

3.5 prisma cli

安装 npm install @prisma/cli --save-dev npm install -g @prisma/cli
prisma studio --experimental // Prisma Studio是数据库的可视编辑器

4. prisma 实践

4.1 加入到已有的项目中

  1. 先决条件 项目中有package.json 机器安装了node 现有的pg数据库并且有个表
  2. 第一步 安装prisma yarn add @prisma/cli --dev 然后初始化项目prisma init 会生成一个包括schema.prisma和.env文件的文件夹prisma
  3. 要连接数据库,修改 schema.prisma文件的datasource 然后执行prisma introspect命令根据前面的数据库生成data modal
  4. 安装prisma client yarn add @prisma/client prisma generate 执行命令生产prisma client库
  5. 新建你的查询 新建index.ts文件 ts-node index.ts运行文件
import { PrismaClient } from "@prisma/client"
const prisma = new PrismaClient()
async function main() {const allUsers = await prisma.user.findMany()console.log(allUsers)
}
main().catch(e => {throw e}).finally(async () => {await prisma.disconnect()})

4.2 从一个新项目开始

  1. mkdir hello-prisma cd hello-prisma
  2. npm init -y npm install @prisma/cli typescript ts-node @types/node --save-dev
  3. 创建tsconfig.json文件
{"compilerOptions": {"sourceMap": true,"outDir": "dist","strict": true,"lib": ["esnext"],"esModuleInterop": true}
}
  1. prisma init 会生成一个包括schema.prisma和.env文件的文件夹prisma
  2. 要连接数据库,修改 schema.prisma文件的datasource 然后执行prisma introspect命令根据前面的数据库生成data modal
  3. 安装prisma client yarn add @prisma/client prisma generate 执行命令生产prisma client库
  4. 新建你的查询 新建index.ts文件 ts-node index.ts运行文件

4.2 从一个新项目开始 利用 prisma migrate

  1. mkdir hello-prisma cd hello-prisma
  2. npm init -y npm install @prisma/cli typescript ts-node @types/node --save-dev
  3. 创建tsconfig.json文件
{"compilerOptions": {"sourceMap": true,"outDir": "dist","strict": true,"lib": ["esnext"],"esModuleInterop": true}
}
  1. prisma init 会生成一个包括schema.prisma和.env文件的文件夹prisma
  2. 要连接数据库,修改 schema.prisma文件的datasource 然后修改文件里的data model
  3. npx prisma migrate save --name init --experimental
    npx prisma migrate up --experimental 执行这两个命令回去创建(修改)数据表
  4. 安装prisma client yarn add @prisma/client prisma generate 执行命令生产prisma client库
  5. 新建你的查询 新建index.ts文件 ts-node index.ts运行文件

nexus

prisma+nexus

其他好用的工具推荐

prisma2.0和nexus搭建graphql后端(1)—prisma2.0相关推荐

  1. redis5.0.5版本搭建集群

                                         redis5.0.5版本搭建集群 安装redis5.0.5版本 将redis5.0.5解压 sudo tar -zxcf re ...

  2. 创业公司 如果让你作技术负责人,你会如何从0搭建公司后端技术栈

    创业公司 如果让你作技术负责人,你会如何从0搭建公司后端技术栈 文章目录 创业公司 如果让你作技术负责人,你会如何从0搭建公司后端技术栈 各系统组件选型 1.项目管理/Bug管理/问题管理 2.DNS ...

  3. 教你从0到1搭建秒杀系统-订单异步处理

    前面几篇我们从限流角度,缓存角度来优化了用户下单的速度,减少了服务器和数据库的压力.这些处理对于一个秒杀系统都是非常重要的,并且效果立竿见影,那还有什么操作也能有立竿见影的效果呢?答案是下单的异步处理 ...

  4. 教你从0到1搭建秒杀系统-限流

    本文是秒杀系统的第二篇,主要讲解接口限流措施.接口限流其实定义也非常广,接口限流本身也是系统安全防护的一种措施,在面临高并发的请购请求时,我们如果不对接口进行限流,可能会对后台系统造成极大的压力,尤其 ...

  5. CentOS 初体验十六:阿里云安装Nexus搭建Maven私有仓库

    转载请注明出处http://blog.csdn.net/zhaoyanjun6/article/details/79198469 本文出自[赵彦军的博客] 简介 mavenCentral 是最早的 m ...

  6. 使用Nexus搭建私有Nuget仓库

    前言 Nuget是ASP .NET Gallery的一员,是免费.开源的包管理工具,专注于在.Net / .Net Core应用开发过程中第三方组件库的管理,相对于传统单纯的dll引用要方便.科学得多 ...

  7. centos利用nexus搭建局域网docker私有仓库

    centos利用nexus搭建局域网docker私有仓库 1.官网下载nexus oss版本 https://sonatype-download.global.ssl.fastly.net/repos ...

  8. 程序员如何从0到1搭建自己的技术博客

    记得刚毕业参加工作时,每天早上到公司后,都会逛逛博客园,看一下各位大牛前辈写的文章,也许是兴趣使然,当时就特别想搭建一个属于自己的独立的技术博客. 时间就是过的这么快,转眼间这么多年过去了,我的这个梦 ...

  9. 搭建前后端分离主流项目完整步骤——在线教育系统(阿里云服务器部署上线)

    前言: 需要源码评论或私我 项目技术栈如下图所示: 本次博客分前后端+部署服务器三个步骤来写 先来看看实现效果: 在线教育系统完整三步骤 前言: 一.后端技术栈 1.ssm+mysql: (1)map ...

  10. Nexus 搭建私有镜像仓库

    Nexus 搭建私有镜像仓库 说明 国内网络环境下直接使用默认的 npm 下载资源过慢,所以很多文章中都建议将 npm 的 registry 切换为 淘宝的 npm 镜像,如下 npm config ...

最新文章

  1. # Ubuntu 配置自带vnc桌面共享
  2. switch的case使用数组C语言,使用常量数组的元素作为switch语句中的case
  3. 拆分命令_在MongoDB分片集群中拆分数据块chunks
  4. Matlab学习笔记——文件的打开与关闭
  5. PyTorch 之 DataLoader
  6. javascript日期时间操作总结
  7. 基于对象和面向对象编程范式辨析和主流编程语言中的应用
  8. rtmp推流直播流程
  9. QPainter 的状态保存与恢复
  10. 计算机辅助项目管理有关论文,项目管理论文
  11. cloudstack基础知识
  12. 金蝶K3案例教程目录2022
  13. 记录一些比较常用的简单jsp模板
  14. api64 gta5缺少steam_GTA5无法启动此程序,因为计算机中丢失steam_api64.dll 游戏打不来 现实这个,win7 64位....
  15. 【神经网络架构】Pyramid Convolution(金字塔卷积模块)论文笔记
  16. 京东云主机使用-搭建简单网页(macOS)
  17. error: The requested URL returned error: 401 Unauthorized while accessing
  18. 第十三届蓝桥杯省赛C++B组题解
  19. 滴滴云服务器搭建网站的一键脚本,一键搭建流控脚本 一键搭建云免流服务器...
  20. 微信小程序--js中string转换为number

热门文章

  1. 如何产生JIC文件(sof+ELF=jic)
  2. 什么是AOP(面向切片编程)
  3. 数学中倒三角:梯度;正三角:拉普拉斯
  4. tampermonkey(油猴)——去除烦人的百度搜索广告
  5. ListFields
  6. 鸿蒙灵根都有哪些,盘点鸿蒙先天十大灵根,你知道哪一个?
  7. 圣诞节来了,雪花纷飞的CSS3动画,还不首页用起来
  8. Python学习笔记(5)-集成开发环境IDLE的使用与调试
  9. php在线图片签名,ElementUi+Vue+Php+fpdf+fpdi 实现文档在线签订(图片水印、手写签名)...
  10. 皮肤测试小软件有哪些,【皮肤测试小程序】皮肤测试小程序有什么功能呢?