Prisma的简介和使用
Prisma的简介和使用
什么是 Prisma
官网介绍:
We simplify query caching,so you don’t have to know how it works
We simplify database subscriptions,so you don’t have to worry about them
We simplify databse migrations,so you don’t have to explain them
We simplify readable date models,so you don’t have to figure out how
We simplify database queries,so you don’t have to manage it
We simplify connecting pooling,so you don’t have to get a PhD in it
翻译过来就是:
我们简化了查询缓存,因此您不必了解它是如何工作的。
我们简化了数据库订阅,因此您不必担心它们。
我们简化了数据库迁移,因此您不必解释它们。
我们简化了可读的日期模型,因此您不必弄清楚如何实现。
我们简化了数据库查询,因此您不必管理它。
我们简化了连接池,因此您不必获得博士学位。
关于 ORM(Object/Relational Mapping),简单来说就是一个可以像操作对象一样操作数据库的工具
就好像 MongoDB 是数据库,Mongoose 是 MongoDB 的 ORM
Prisma 更加强大,它使用更加方便,又支持 PostgreSQL、MySQL、MongoDB、SQL Server和SQLite 等多个数据库
如果要学习 Prisma ,最简单的方法就是去官网看一下它的教学
- Build A Fullstack App with Remix, Prisma & MongoDB
- Building a REST API with NestJS, PostgreSQL, Swagger and Prisma
我相信只要你看完以上几个视频,对 Prisma 的已经会用了,之后叠加 AI 辅助,就能写出你想要的增删改查了
Prisma 组成
Prisma 的产品有很多,其中 Prisms ORM 是我们使用的最最关注的
Prisma ORM是一个基于 Nodejs 和 TypeScript 的 ORM,由于其直观的数据模型、自动迁移、类型安全和自动完成功能,它在处理数据库时解锁了开发人员的新体验。
除此之外,还有 Prisma Optimize、Prisma Accelerate、Prisma Pules、以及新出的Prisma Postgres
- Prisma Optimize:分析查询、生成见解并提供建议以加快数据库查询速度
- Prisma Accelerate:全局数据库缓存,具有可扩展的连接池,可加快查询速度
- Prisma Pules:允许使用类型安全的模型流实时响应数据库更改
- Prisma Postgres:托管的 PostgreSQL 服务
其中我们最关注的 Prisms ORM 由以下工具组成:
- Prisma Client:自动生成且类型安全的Node.js和TypeScript查询构建器
- Prisma Migrate:声明式数据建模和迁移系统
- Prisma Studio:用于查看和编辑数据库中的数据的可视化工具
Prisma 要学习的点
因为 Prisma 要做的是跨数据库,所以它分为两部分,一部分是对数据库的连接以及定义 Schema,二是由 Prisma Client 做的增删改查
第一部分做的是兼容各个数据库的不同,以 Prisma ORM 的标准来定义 Schema。简单说就是 数据类型的映射,例如 Prisma ORM 的 String
在 SQLite 里是 TEXT
,在 PostgreSQL 就是text
,而在 MySQL 里是VARCHAR(191)
而且定义 Schema 后的表的关系也是 Prisma 的自定义的标准
第二部分就是Prisma Client 做的增删改查,看文档一目了然
当你修改 Schema (就是你定义的表)后,你需要将其迁移到数据库中,命令为 prisma migrate dev --name xxx
Prisma 实操
第一步:下载 prisma
pnpm i prisma -D
使用
pnpm prisma
命令能获得 Prisma 的各种介绍以及命令行的使用Prisma is a modern DB toolkit to query, migrate and model your database (https://www.prisma.io) Usage $ prisma [command] Commands init Setup Prisma for your app generate Generate artifacts (e.g. Prisma Client) db Manage your database schema and lifecycle migrate Migrate your database studio Browse your data with Prisma Studio validate Validate your Prisma schema format Format your Prisma schema Flags --preview-feature Run Preview Prisma commands Examples Setup a new Prisma project $ prisma init Generate artifacts (e.g. Prisma Client) $ prisma generate Browse your data $ prisma studio Create migrations from your Prisma schema, apply them to the database, generate artifacts (e.g. Prisma Client) $ prisma migrate dev Pull the schema from an existing database, updating the Prisma schema $ prisma db pull Push the Prisma schema state to the database $ prisma db push
第二步:初始化
pnpm prisma init
这一步会在根目录下创建 prisma 文件,并在其中创建
schema.prisma
文件
第三步:添加 schma.prisma 以及.env 中的数据库地址
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
DATABASE_URL="postgresql://username:password@localhost:5432/mydb?schema=public"
第四步:下载@prisma/client 客户端、vscode 下载 prisma 插件
pnpm i @prisma/client
第五步:回到 schma.prisma 写 model
即定义 User 模型
model UserApiLimit {
id String @id @default(cuid())
userId String @unique
count Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
第七步:同步数据库
将 prisma 模型同步到数据库
pnpm prisma db push
如果是一个已经有数据的项目,就不能使用这个命令,而是用
prisma migrate
迁移
第八步:生成 Prisma Client
前面同步数据库时,已经执行了 prisma generate
。所以现在不需要再次执行了,但是一旦 Prisma Schema 文件发生了变动,比如修改了模型,就需要再来执行下这个命令,重新生成 Prisma Client。
pnpm prisma generate
第九步:在线查看数据库
pnpm prisma studio
第十步:@prisma/client
链接数据库
import { PrismaClient } from '@prisma/client'
declare global {
var prisma: PrismaClient | undefined
}
const prisma = global.prisma || new PrismaClient()
if (process.env.NODE_ENV !== 'production') global.prisma = prisma
export default prisma
Prisma Schema
Prisma Schema 是在最大程序上贴近数据库结构描述的基础上,对关联关系进行进一步抽象
字段由下面四种描述组成:
- 字段名。
- 字段类型。
- 可选的类型修饰。
- 可选的属性描述。
model Tag {
name String? @id
}
在这个描述里,包含字段名 name
、字段类型 String
、类型修饰 ?
、属性描述 @id
。
prisma Client CRUD
使用 create
创建一条记录:
const user = await prisma.user.create({
data: {
email: "elsa@prisma.io",
name: "Elsa Prisma",
},
});
使用 createMany
创建多条记录:
const createMany = await prisma.user.createMany({
data: [
{ name: "Bob", email: "bob@prisma.io" },
{ name: "Bobo", email: "bob@prisma.io" }, // Duplicate unique key!
{ name: "Yewande", email: "yewande@prisma.io" },
{ name: "Angelique", email: "angelique@prisma.io" },
],
skipDuplicates: true, // Skip 'Bobo'
});
使用 findUnique
查找单条记录:
const user = await prisma.user.findUnique({
where: {
email: "elsa@prisma.io",
},
});
对于联合索引的情况:
model TimePeriod {
year Int
quarter Int
total Decimal
@@id([year, quarter])
}
需要再嵌套一层由 _
拼接的 key:
const timePeriod = await prisma.timePeriod.findUnique({
where: {
year_quarter: {
quarter: 4,
year: 2020,
},
},
});
使用 findMany
查询多条记录:
const users = await prisma.user.findMany();
可以使用 SQL 中各种条件语句,语法如下:
const users = await prisma.user.findMany({
where: {
role: "ADMIN",
},
include: {
posts: true,
},
});
使用 update
更新记录:
const updateUser = await prisma.user.update({
where: {
email: "viola@prisma.io",
},
data: {
name: "Viola the Magnificent",
},
});
使用 updateMany
更新多条记录:
const updateUsers = await prisma.user.updateMany({
where: {
email: {
contains: "prisma.io",
},
},
data: {
role: "ADMIN",
},
});
使用 delete
删除记录:
const deleteUser = await prisma.user.delete({
where: {
email: "bert@prisma.io",
},
});
使用 deleteMany
删除多条记录:
const deleteUsers = await prisma.user.deleteMany({
where: {
email: {
contains: "prisma.io",
},
},
});
使用 include
表示关联查询是否生效,比如:
const getUser = await prisma.user.findUnique({
where: {
id: 19,
},
include: {
posts: true,
},
});
这样就会在查询 user
表时,顺带查询所有关联的 post
表。关联查询也支持嵌套:
const user = await prisma.user.findMany({
include: {
posts: {
include: {
categories: true,
},
},
},
});
筛选条件支持 equals
、not
、in
、notIn
、lt
、lte
、gt
、gte
、contains
、search
、mode
、startsWith
、endsWith
、AND
、OR
、NOT
,一般用法如下:
const result = await prisma.user.findMany({
where: {
name: {
equals: "Eleanor",
},
},
});
这个语句代替 sql 的 where name="Eleanor"
,即通过对象嵌套的方式表达语义。
Prisma 也可以直接写原生 SQL:
const email = "emelie@prisma.io";
const result = await prisma.$queryRaw(
Prisma.sql`SELECT * FROM User WHERE email = ${email}`
);