nestjs的orm之Prisma
orm
orm 其实官方推荐的TypeORM,我们这里学习Prisma!
使用Prisma会造成后续问题,比如 再生成 openJson 的时候, @ApiBody需要的class(dto也叫元数据),而Prisma生成是 type(纯 ts 语法,编译的时候会被去掉)。
https://blog.csdn.net/lok_p/article/details/147885850
https://github.com/prisma/prisma/issues/8334
https://stackoverflow.com/questions/76978671/nestjs-and-prisma-do-we-really-need-dtos-for-validation-when-we-could-use-prism
https://zhuanlan.zhihu.com/p/1936022466943260144
https://www.prisma.io/docs/orm/more/comparisons/prisma-and-typeorm
不过 TypeORM 也并非有多好,无法和比较困难的逆向是他的弱点,甚至找到了三方的吐槽
https://github.com/Kononnable/typeorm-model-generator/issues/329

安装与初始化
pnpm add prisma -D
pnpm dlx prisma init
执行完毕后,该命令会创建一个包含以下内容的 prisma 目录:
schema.prisma:指定数据库连接并包含数据库模式
.env:一个 dotenv 文件,通常用于将数据库货其它配置的环境变量
prisma.config.ts:prisma 配置文件
注意的是,需要删除prisma.config.ts,否则后续步骤会失败!
设置prisma数据库连接
.env配置如下
DATABASE_URL="mysql://用户名:密码@主机:端口/数据库"
schema.prisma配置如下
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
prisma生成模型
以下命令会根据数据库中的表结构生成模型到项目中(prisma/schema.prisma)
pnpm dlx prisma db pull
如果您没有数据库表结构,可以走反向工程的工作流,即手动在 prisma/schema.prisma中定义模型,然后执行以下命令将模型同步到数据库中(这里有官方指引):
npx prisma migrate dev --name init
生成并使用prisma客户端
Prisma Client会根据您的模型生成 dao 层代码(即封装了 crud 的操作)。
安装过程中 Prisma 会自动为您调用 prisma generate 命令
pnpm add @prisma/client
或者您也可以手动调用(主要是针对后续更新模型后 需要再次生成)
pnpm dlx prisma generate
prisma generate 命令会读取您的 Prisma 架构,并更新位于 node_modules/@prisma/client 中的生成 Prisma 客户端库。
最后我们使用客户端
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
prisma.user.update({...})
优雅的使用prisma客户端
我们创建prisma.service.ts来管理prisma客户端的生命周期,并且将其注册为nestjs的provider,然后在需要使用的地方注入即可!
(为方便演示,我还创建了个UserController,用来调用,所以这里也显式注册到app.module.ts的controllers中)
app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserController } from 'src/user/user.controller';
import { PrismaService } from 'src/prisma/prisma.service';
@Module({
controllers: [AppController, UserController],
providers: [AppService, PrismaService],
})
export class AppModule {}
prisma.service.ts
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
}
最后在user.controller.ts中使用
import { Controller, Get } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { user as User } from '@prisma/client';
@Controller('user')
export class UserController {
constructor(private prisma: PrismaService) {}
@Get()
getUsers(): Promise<User[]> {
return this.prisma.user.findMany();
}
}
现在试试效果 http://localhost:3000/user
生成dto
并不支持生成dto class,不过好在有三方插件 prisma-class-generator(prisma-generator-nestjs-dto已经废弃了) 支持
如果生成报错,建议安装全局!
如果只有输出没有生成文件,是因为漏了配置!

浙公网安备 33010602011771号