## interior_helper 開發-資料庫學習筆記 schema --- ```javascript= id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt ``` id: 自動生成 UUID createdAt: 自動設置為當前時間 updatedAt: 自動更新時間戳 `index` * 加速用戶登錄查詢 * 加速用戶註冊時的郵箱重複檢查 * 優化按郵箱搜索用戶的操作 ```javascript= model User { // ... @@index([email]) } // 常見使用場景 await prisma.user.findUnique({ where: { email } }); // 登錄 await prisma.user.findFirst({ where: { email } }); // 檢查郵箱是否存在 await prisma.user.findMany({ where: { email: { contains: 'example.com' } } }); // 搜索特定域名的用戶 ``` Prisma實體操作 --- `include:` * 可以同時獲取關聯模型的數據 * 會增加查詢的複雜度 * 只在需要關聯數據時才使用 ```javascript= include: { tasks: true, }, // 可以選擇性包含關聯數據的特定字段 const project = await prisma.project.findFirst({ where: { id }, include: { tasks: { select: { title: true, status: true } } } }); ``` --- deleteProject 時 關聯的task也會被刪除 需要額外寫上邏輯嗎? Prisma自動會處理 ```javascript= await prisma.project.delete({ where: { id, userId: authReq.user.id }, }); ... model Task { project Project @relation(fields: [projectId], references: [id], onDelete: Cascade) } ``` * onDelete: Cascade 表示當父記錄(Project)被刪除時,所有相關的子記錄(Tasks)也會被自動刪除 * 這是在資料庫層面處理的,非常高效且可靠 prisma 指令 --- ```javascript npx prisma generate npx prisma db push npx prisma studio ``` 避免熱模組重新加載 --- ```javascript import { PrismaClient } from '@prisma/client'; const globalForPrisma = global as unknown as {prisma: PrismaClient}; export const prisma = globalForPrisma.prisma || new PrismaClient({log: ['query']}); if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma; ``` 雙重型別斷言 (as unknown as { prisma: PrismaClient }) 的用途: 先將 global 轉型為 unknown 類型。再轉型為一個包含 prisma 屬性 的物件 類型為 PrismaClient 為什麼不直接 as { prisma: PrismaClient } 還需要先 as unknown? 因為 TypeScript 不允許直接在兩個不相關的型別之間進行轉換。 寫法思考 --- ```javascript updateData.startDate = startDate ? new Date(startDate) : null; // 這樣寫好 還是這樣寫好 updateData.startDate = new Date(startDate) ; // 上者好 // 使用者可能想要清除日期(設為 null),當 startDate 為空 會拋出錯誤 // 當 startDate 是 null 或 undefined 時: new Date(null) // Invalid Date new Date(undefined) // Invalid Date ``` --- return { status: 'success', data: projects } 這樣寫好 還是直接 return projects 好 ?  物件寫法 * 一致性: 所有 action 都使用相同的返回格式 前端處理邏輯可以統一 更容易維護和擴展 * 更好的錯誤追踪: 可以包含更多錯誤信息 可以添加錯誤代碼或其他元數據 便於調試和日誌記錄 > 避免 undefined 或 null 的問題 ```javascript async function getProjects() { try { const session = await auth() if (!session?.user?.id) { return null // 或 undefined?或 throw error?不夠明確 } const projects = await prisma.project.findMany({ where: { userId: session.user.id } }) return projects // 可能是空數組 [] 或有數據的數組 } catch (error) { return null // 或 undefined?或 throw error? } } const projects = await getProjects() if (!projects) // !projects 可能是因為: // 1. 未授權(null) // 2. 發生錯誤(null) // 3. 確實沒有數據([]) // 無法區分具體是哪種情況! ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up