Project References
{
"references": [
{ "path": "../ui" },
{ "path": "../hooks" },
{ "path": "../app" }
]
}
composite
新建项目:
npm i -g @nestjs/cli
nest new nest-prisma
主要文件结构:
app.controller.ts
API 路由定义文件 app.service.ts
在 Service 层去处理数据库交互、BFF、日志等逻辑,然后供 Controller 层调用 UpdateUser
处理方法,那 Service 层也要有专门的 UpdateUser
方法,更好的方法是将 Service 拆得更细一些,在未来新增 Controller 时,只需要按照逻辑重新组装 Service 即可app.module.ts
应用的核心文件,需要这个模块才能在 main.ts
中去启动应用 .module.ts
文件来实现对业务逻辑的模块拆分,如 user.module.ts
、upload.module.ts
等main.ts
应用的入口文件,负责启动应用 ORM 库(Object-Relational Mapping),其实就是编程语言到 SQL 的映射,无需学习 SQL 的使用,直接用最熟悉的代码调用方法,即可与数据库进行交互。
NodeJs 中的 ORM 目前基本都是通过 js / ts 文件进行定义的,比如 Sequelize、TypeORM 等,均是通过面向对象的方式进行数据库实体的定义。
Prisma 最特殊的一点,它使用自己的 SDL(Schema Define Language,也可以说是 DSL ,Domain-Specified Language)来声明一个实体。
初始化 Prisma:
npx prisma init
npm i prisma -g
npm i @prisma/client -D
声明 Schema:
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Tag {
id String @id @default(cuid())
name String
description String?
Article Article[]
}
model Category {
id String @id @default(cuid())
name String
description String?
Article Article[]
}
model Article {
id Int @id @default(autoincrement())
title String?
description String @default("there is no description")
content String
visible Boolean @default(true)
tag Tag[]
category Category[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
生成 Client:
prisma generate
Prisma Client 会被生成到 node_modules/@prisma/client
目录下,可以通过 import { PrismaClient } from '@prisma/client'
来引入。
将 Prisma 相关逻辑封装到 Service 中:
import {
Injectable,
OnApplicationShutdown,
OnApplicationBootstrap,
} from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService
extends PrismaClient
implements OnApplicationBootstrap, OnApplicationShutdown
{
constructor() {
super();
}
async onApplicationBootstrap() {
await this.$connect();
}
async onApplicationShutdown(signal?: string) {
await this.$disconnect();
}
}
实例化:
import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Global()
@Module({
providers: [PrismaService],
exports: [PrismaService],
})
export default class PrismaModule {}
在 app.module.ts
中导入:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import PrismaModule from './data/prisma.module';
@Module({
imports: [
PrismaModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
声明相关类型:
export type { Article, Tag, Category } from '@prisma/client';
import type { Prisma } from '@prisma/client';
export type ArticleCreateInput = Prisma.ArticleCreateInput;
export type ArticleUpdateInput = Prisma.ArticleUpdateInput &
Prisma.ArticleWhereUniqueInput;
export type TagCreateInput = Prisma.TagCreateInput;
export type TagUpdateInput = Prisma.TagUpdateInput & Prisma.TagWhereUniqueInput;
export type CategoryCreateInput = Prisma.CategoryCreateInput;
export type CategoryUpdateInput = Prisma.CategoryUpdateInput &
Prisma.CategoryWhereUniqueInput;
export type MaybeArray<T> = T | T[];
export type MaybeNull<T> = T | null;