技术栈
- nextjs
- nestjs
- prisma
所学知识
- Nextjs组件渲染,状态,路由
- docker启动Mysql容器
- prisma操作Mysql(CRUD)
- 允许跨域请求API
- TanStack Query异步状态管理
- fetch api
- 服务器组件预请求数据
- nestjs 管道和异常处理
- 检测id是否正整数
Docker启动Mysql容器
compose.yml
name: 'todoList'
version: '3.8'
services:
mysql:
restart: always
container_name: todolist
image: mysql:8
volumes:
- ./mysql/datadir:/var/lib/mysql
- ./mysql/config/my.cnf:/etc/mysql/my.cnf
environment:
- "MYSQL_ROOT_PASSWORD=root"
- "TZ=Asia/Shanghai"
ports:
- 3306:3306
切换到compose.yml所在目录,cmd
docker-compose up
![[Pasted image 20241124230249.png]]
初始化prisma
npm install prisma --save-dev
npx prisma init
生成配置文件
设置数据库连接(mysql)
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
设置数据库连接环境变量
DATABASE_URL="mysql://root:root@localhost:3306/todos?schema=public"
- todos是数据库名
设置表
model Todo {
id Int @id @default(autoincrement())
title String
completed Boolean? @default(false)
createdAt DateTime @default(now())
}
npx prisma migrate dev --name init
![[Pasted image 20241124221851.png]]
回到初始化状态(测试用)
会删除数据库数据
,但是prisma配置内容还在
npx prisma migrate reset
定义prisma client
npm install @prisma/client
Prisma Client 是一个类型安全的数据库客户端,它是从 Prisma 模型定义生成的。由于这种方法,Prisma Client 可以公开专门为您的模型量身定制的 CRUD 操作。
请注意,在安装过程中,Prisma 会自动为您调用 prisma generate
命令。将来,您需要在每次更改 Prisma 模型后
运行此命令,以更新生成的 Prisma Client。
使用prisma client
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();
}
}
onModuleInit 是可选的 — 如果你省略它,Prisma 将在第一次调用数据库时延迟连接。
注意
app.module要引入PrismaService
import { Module } from '@nestjs/common';
import { PrismaService } from 'src/prisma.service';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TodoController } from './todo/todo.controller';
import { TodoService } from './todo/todo.service';
@Module({
imports: [],
controllers: [AppController, TodoController],
providers: [AppService, TodoService, PrismaService],
})
export class AppModule {}
不然报错
prisma调用数据库操作
接下来,您可以编写可用于从 Prisma 架构对 todo
模型进行数据库调用的服务。
增
import {
Body, Controller, Get, Post } from '@nestjs/common';
import {
TodoService } from 'src/todo/todo.service';
@Controller('todo')
export class TodoController {
constructor(private readonly todoService: TodoService) {
}
@Post()
async createTodo(@Body() createTodoDto: any) {
return this.todoService.createTodo(createTodoDto);
}
}
import {
Injectable } from '@nestjs/common';
import {
PrismaService } from 'src/prisma.service';
@Injectable()
export class TodoService {
constructor(private prisma: PrismaService) {
}
async createTodo(data: any) {
const todo = await this.prisma.todo.create({
data: {
title: data.title,
completed: false,
},
});
return todo;
}
}
- private
这确保了封装,这意味着没有其他类或外部代码可以直接访问 todoService 属性,这是维护干净且可预测的代码的良好做法。
- readonly
这是有益的,因为服务实例应在控制器的整个生命周期中保持不变。它可以防止意外重新分配 todoService 属性,这可能会导致 bug。
删
@Delete(':id')
async deleteTodoById(@Param('id') id: string) {
return this.todoService.deleteTodoById(+id);
}
async getTodoById(id: number