Appearance
Prisma 快速入门
Prisma是现代数据库工具包,它提供了类型安全的数据库访问和直观的数据建模。Prisma ORM通过其类型安全的查询API、自动迁移和直观的数据建模语言,简化了数据库操作。
什么是Prisma
Prisma是一个现代化的数据库工具包,包含以下组件:
- Prisma Client:类型安全的数据库客户端
- Prisma Migrate:数据库迁移系统
- Prisma Studio:数据库GUI工具
- Prisma Schema:数据建模语言
主要特性
- 类型安全:完全类型安全的数据库查询
- 直观API:简洁易用的查询API
- 数据建模:直观的模式定义语言
- 自动迁移:安全的数据库迁移
- 数据库支持:支持PostgreSQL、MySQL、SQLite、SQL Server、MongoDB
安装Prisma
初始化项目
bash
# 创建新项目
mkdir my-prisma-project
cd my-prisma-project
npm init -y
# 安装Prisma作为开发依赖
npm install prisma --save-dev
# 安装Prisma Client
npm install @prisma/client
初始化Prisma
bash
# 初始化Prisma(创建schema文件和node_modules/.prisma目录)
npx prisma init
这将创建以下文件:
prisma/schema.prisma:Prisma模式文件.env:环境变量文件(包含数据库连接URL)
配置数据库连接
数据库连接配置
编辑生成的.env文件:
text
# PostgreSQL
DATABASE_URL="postgresql://user:password@localhost:5432/mydb?schema=public"
# MySQL
DATABASE_URL="mysql://user:password@localhost:3306/mydb"
# SQLite
DATABASE_URL="file:./dev.db"
# SQL Server
DATABASE_URL="sqlserver://localhost:1433;database=mydb;user=user;password=password;"
# MongoDB (实验性)
DATABASE_URL="mongodb+srv://user:password@cluster.mongodb.net/mydb"
配置Prisma Schema
编辑prisma/schema.prisma文件:
prisma
// prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql" // 或 "mysql", "sqlite", "sqlserver", "mongodb"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
}
安装数据库驱动
根据使用的数据库安装相应的驱动:
bash
# PostgreSQL
npm install pg
# MySQL
npm install mysql2
# SQLite
npm install sqlite3
# SQL Server
npm install tedious
# MongoDB (实验性)
npm install @prisma/adapter-mongodb
数据库迁移
创建和应用迁移
bash
# 创建并应用迁移
npx prisma migrate dev --name init
# 或者使用别名
npx prisma migrate dev
生成迁移文件
这将创建一个迁移文件,例如:
prisma/migrations/
└── 20231201235959_init/
└── migration.sql
在应用中使用Prisma Client
基本设置
javascript
// app.js
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function main() {
// 创建用户
const user = await prisma.user.create({
data: {
name: 'Alice',
email: 'alice@prisma.io',
},
})
console.log(user)
// 创建帖子
const post = await prisma.post.create({
data: {
title: 'Hello Prisma',
content: 'This is my first post',
author: {
connect: { email: 'alice@prisma.io' },
},
},
})
console.log(post)
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})
使用ES6模块
javascript
// app.mjs
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
// 查询所有用户
const allUsers = await prisma.user.findMany()
console.log(allUsers)
// 查询特定用户及其帖子
const userWithPosts = await prisma.user.findUnique({
where: { email: 'alice@prisma.io' },
include: { posts: true },
})
console.log(userWithPosts)
}
main()
.finally(async () => {
await prisma.$disconnect()
})
基本CRUD操作
创建数据
javascript
// 创建单个记录
const user = await prisma.user.create({
data: {
name: 'John Doe',
email: 'john@example.com',
},
})
// 创建多个记录
const users = await prisma.user.createMany({
data: [
{ name: 'User 1', email: 'user1@example.com' },
{ name: 'User 2', email: 'user2@example.com' },
],
})
读取数据
javascript
// 查询单个记录
const user = await prisma.user.findUnique({
where: { email: 'john@example.com' },
})
// 查询多个记录
const users = await prisma.user.findMany({
where: {
name: { contains: 'John' },
},
take: 10, // 限制结果数量
orderBy: { name: 'asc' }, // 排序
})
// 计数
const userCount = await prisma.user.count({
where: { email: { endsWith: '@example.com' } },
})
更新数据
javascript
// 更新单个记录
const updatedUser = await prisma.user.update({
where: { email: 'john@example.com' },
data: { name: 'John Smith' },
})
// 更新多个记录
const updatedUsers = await prisma.user.updateMany({
where: { name: { contains: 'Smith' } },
data: { name: { set: 'Updated Name' } },
})
// 条件更新
const result = await prisma.user.updateMany({
where: { email: { endsWith: '@old-domain.com' } },
data: {
email: {
// 在实际应用中,这需要更复杂的逻辑来更新邮箱
}
},
})
删除数据
javascript
// 删除单个记录
const deletedUser = await prisma.user.delete({
where: { email: 'john@example.com' },
})
// 删除多个记录
const deletedCount = await prisma.user.deleteMany({
where: { name: { contains: 'Spam' } },
})
关系查询
包含关联数据
javascript
// 获取用户及其所有帖子
const userWithPosts = await prisma.user.findUnique({
where: { id: 1 },
include: {
posts: true,
},
})
// 获取帖子及其作者
const postWithAuthor = await prisma.post.findUnique({
where: { id: 1 },
include: {
author: true,
},
})
// 嵌套包含
const userWithPostsAndComments = await prisma.user.findUnique({
where: { id: 1 },
include: {
posts: {
include: {
comments: true,
},
},
},
})
过滤关联数据
javascript
// 获取有特定帖子的用户
const usersWithPublishedPosts = await prisma.user.findMany({
where: {
posts: {
some: {
published: true,
},
},
},
include: {
posts: {
where: {
published: true,
},
},
},
})
Prisma Studio
Prisma Studio是一个数据库GUI工具,用于查看和编辑数据库中的数据。
bash
# 启动Prisma Studio
npx prisma studio
这将在浏览器中打开http://localhost:5555,您可以在其中查看和编辑数据库数据。
数据模型定义
基本字段类型
prisma
model User {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
email String @unique
name String?
isAdmin Boolean @default(false)
age Int?
height Float?
role Role @default(USER)
permissions String[]
}
enum Role {
USER
ADMIN
MODERATOR
}
关系定义
prisma
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
// 一对多关系
posts Post[]
// 一对一关系
profile Profile?
}
model Profile {
id Int @id @default(autoincrement())
bio String?
user User @relation(fields: [userId], references: [id])
userId Int @unique
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
}
高级查询
连接查询
javascript
// 使用where条件查询
const posts = await prisma.post.findMany({
where: {
AND: [
{ title: { contains: 'Prisma' } },
{ published: true },
{ author: { email: { endsWith: '@prisma.io' } } },
],
},
include: {
author: {
select: {
name: true,
email: true,
},
},
},
})
// 聚合查询
const result = await prisma.post.aggregate({
where: { published: true },
_count: true,
_avg: { authorId: true },
_sum: { id: true },
})
原生SQL查询
javascript
// 原生SQL查询(仅适用于SQL数据库)
const posts = await prisma.$queryRaw`SELECT * FROM Post WHERE title LIKE ${'%Prisma%'}`
// 原生SQL执行
const result = await prisma.$executeRaw`UPDATE Post SET published = true WHERE id = ${postId}`
连接池配置
javascript
// 自定义Prisma Client配置
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient({
log: ['query', 'info', 'warn', 'error'], // 启用查询日志
datasourceUrl: process.env.DATABASE_URL,
})
// 或者使用更详细的配置
const prisma = new PrismaClient({
datasources: {
db: {
url: process.env.DATABASE_URL,
},
},
log: [
{ level: 'query', emit: 'event' }, // 记录所有查询
{ level: 'info', emit: 'stdout' },
{ level: 'warn', emit: 'stdout' },
{ level: 'error', emit: 'stdout' },
],
})
// 监听查询事件
prisma.$on('query', (e) => {
console.log('Query: ' + e.query)
console.log('Params: ' + e.params)
console.log('Duration: ' + e.duration + 'ms')
})
完整示例应用
javascript
// server.js - Express + Prisma示例
const express = require('express')
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
const app = express()
app.use(express.json())
// 创建用户
app.post('/users', async (req, res) => {
const { name, email } = req.body
const user = await prisma.user.create({
data: {
name,
email,
},
})
res.json(user)
})
// 获取所有用户
app.get('/users', async (req, res) => {
const users = await prisma.user.findMany()
res.json(users)
})
// 获取特定用户
app.get('/users/:id', async (req, res) => {
const { id } = req.params
const user = await prisma.user.findUnique({
where: { id: Number(id) },
include: { posts: true },
})
res.json(user)
})
// 创建帖子
app.post('/posts', async (req, res) => {
const { title, content, authorEmail } = req.body
const post = await prisma.post.create({
data: {
title,
content,
author: {
connect: { email: authorEmail },
},
},
})
res.json(post)
})
// 启动服务器
const server = app.listen(3000, async () => {
console.log('Server started on http://localhost:3000')
console.log('Prisma is connected to the database')
})
// 优雅关闭
process.on('SIGINT', async () => {
console.log('\nShutting down gracefully...')
await prisma.$disconnect()
server.close(() => {
console.log('Server closed')
process.exit(0)
})
})
常用命令
bash
# 生成Prisma Client(在模式更改后)
npx prisma generate
# 检查模式
npx prisma db pull
# 推送模式到数据库(非生产环境)
npx prisma db push
# 部署迁移到生产数据库
npx prisma migrate deploy
# 验证模式
npx prisma validate
# 格式化模式文件
npx prisma format
总结
Prisma提供了一个现代化的数据库访问解决方案,具有类型安全、直观API和强大的功能。通过本章的学习,你应该已经掌握了Prisma的基本概念和使用方法。在接下来的章节中,我们将深入探讨Prisma的高级特性和最佳实践。