本篇介绍利用流行库Prisma与数据库的连接。
我们将学习设置Prisma,定义数据模型,创建迁移,执行 CRUD 操作。
安装MySQL
Prisma支持各种数据库,我们选择MySQL。官网:mysql.com,进入 downloads,下载并安装Community版。
MySQL官网提供了客户端工具 “MySQL Workbench”,可以下载使用。更好用的工具是DataGrip,可以免费使用30天。
官网:https://www.jetbrains.com/datagrip/
设置Prisma
Prisma是非常流行的ORM(Object Relational Mapper),官网:
需要说明的是,本文只是Prisma的入门介绍,为学习Prisma打下基础,更多的内容需要自己去阅读官方文档。
安装VSCode的Prisma插件,它能协助我们编码时进行语法提示和自动完成。
安装Prisma:
npm i prisma
Prisma带来一个命令行接口,可以运行 npx prisma查看相关命令说明。
初始化:
npx prisma init
执行初始化命令 prisma做了以下一些事情:
创建了prisma文件夹,并在其下创建schema.prisma文件;创建了 .env文件。
默认prisma使用postgresql,我们需要修改成mysql,并配置正确数据库字符串(同时确保我们实际的MySQL数据库已新建了该数据库nextapp)。同时为了避免敏感信息也上传至git,在.gitignore上添加 .env。
定义模型
应用程序都有模型,比如在线商城应用就有商品、购物车、顾客等模型。这些模型最终要跟数据库匹配。
我们在prisma/schema.prisma中定义模型。
模型的命名使用Pascal命名法,即首字母大写的驼峰形式。之前我们安装了Prisma扩展,在VSCode编码时都有提示非常方便。
Prisma提供了一个命令,用于格式化模型。
npx prisma format
User模型非常简单,我们使用了最基本的类型,如Int, String, Boolean等,实际上模型可以很复杂,可以google查询 “prisma model” 了解进一步的知识。
创建迁移
创建模型后,需要将其同步到数据库,用到的命令就是 prisma migrate dev,如果数据库使用非SQL的,就用命令 prisma db push。
npx prisma migrate dev
运行迁移命令会要求提供一个迁移名称,这里输入Initial。Prisma会根据配置的数据库信息生成 “时间+迁移名”的文件夹,再在其下生成 migration.sql,该sql就是该迁移在数据库执行的命令语句。
不同的数据库根据语法差异生成的sql会有所差别。
我们用DataGrip查看数据库,发现已创建了User表。另外还有一个以下划线开头的 _prisma_migrations表,它用于记录迁移过程,我们看到刚才的迁移已在表内。
DataGrip可以很方便创建数据行,可以尝试创建。
修改模型User,添加一个属性registeredAt。
然后再进行迁移 npx prisma migrate dev。迁移前可以进行格式化 npx prisma format。
检查已生新的迁移目录及迁移SQL,同时我们可以看到数据表User已添加了registeredAt字段。
创建 prisma 客户端
创建Prisma模型并连接数据库后,我们还要创建Client供应用使用。
在prisma目录下新建client.ts,创建并导出 prisma的client。该client可以操作模型也即数据库的表(添加、读取、更新、删除)。
我们当然可以等到操作模型时才创建client。但一般而言,要保持只创建一个prisms的client实例,所以专门创建了client.ts文件。
某模块首次导入client.ts 的 prisma时,它会创建一个client实例;其他模块再次导入时,它会直接在缓存中获取,不会再创建实例。所以利用该client.ts模块,我们可以使prisma只有一个实例。但开发环境有快速刷新的特性,可能会产生多个prisma的错误。如何解决这个问题?
Google搜索 “ prisma next.js prismaclient” 找相关解决方案。借用一段代码代替 client.ts的内容。
这段代码使用globalForPrisma实现单一实例。后续基本不会再去改动,复制就好。
获取数据
我们修改API端点 /api/users 从数据库里获取数据。
修改api/users/route.tsx,由于从数据库获取数据,需要加上async。findMany用于获取多个对象,可以使用 where进行筛选,这里不加表示获取所有对象。
访问 /api/users,得到User表的所有记录。
再来修改获取单个对象的API。
修改 /api/users/[id]/route.tsx,获取单个对象用findUnique,并使用where进行筛选。
访问 /api/users/1
创建数据
创建是POST数据,我们的数据格式增加了email,用zod建的验证规则要作相应修改。
然后开始修改/api/users/route.tsx的POST函数。
除了常规的数据验证,我们还需要验证请求的email在数据库里是不存在的,因为数据模型有要求,否则会出错。
创建数据的属性要逐一赋值,不建议使用 {data:body}的方式,否则会接受到不可预知的属性,尤其是 nosql的数据库更要注意。
在我们的数据模型中,followers, isActive等都已设了默认值,所以可以不必传值。
在Postman中测试。
更新数据
更新数据,修改/api/users/[id]/route.tsx。
验证数据是否正确,查找是否存在更新的用户,再进行更新。prisma的更新有两个参数:where用于筛选用户,data是要更新的数据。
删除数据
最后一块拼图就是删除数据, 修改 /api/users/[id]/route.tsx。
同样很简单,查看是否存在要删除的用户,然后进行删除。
有一点要注意,数据库的操作都要加上await async 标记,有时会忘记。
练习:在数据库中存储Products
在 prisma/schema.prisma 创建模型Product,再进行迁移,检查数据库已生成Product表。
修改 /app/products/route.tsx。并在postman中测试。很常规没有什么新鲜事。
小结
本文学习了利用流行库Prisma实现与数据库的连接,包括如何设置Prisma,定义数据模型,创建迁移,执行 CRUD 操作等内容。
下一篇介绍文件的上传。