1. ORM 选型对比
| 特性 | Prisma | TypeORM | Mongoose |
|---|---|---|---|
| 数据库 | PostgreSQL/MySQL/SQLite/MongoDB/SQL Server | 关系型为主 | MongoDB 专用 |
| 类型安全 | ⭐⭐⭐⭐⭐(自动生成类型) | ⭐⭐⭐⭐(装饰器) | ⭐⭐⭐(手动定义) |
| 查询 API | 链式、类型安全 | QueryBuilder/Repository | 链式查询 |
| 迁移 | 内置 Migration | TypeORM CLI | 不适用 |
| 性能 | 中等(查询引擎) | 高 | 高 |
| 学习曲线 | 中等 | 陡峭 | 平缓 |
2. Prisma 实战
2.1 Schema 定义
// schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
createdAt DateTime @default(now())
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
}
2.2 客户端使用
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// 创建
const user = await prisma.user.create({
data: { email: 'alice@example.com', name: 'Alice' }
});
// 查询 + 关联
const posts = await prisma.post.findMany({
where: { published: true },
include: { author: true },
orderBy: { createdAt: 'desc' },
take: 10
});
// 事务
const [user, post] = await prisma.$transaction([
prisma.user.create({ data: { email: 'bob@example.com' } }),
prisma.post.create({ data: { title: 'Hello', authorId: 1 } })
]);
2.3 迁移
npx prisma migrate dev --name init # 开发迁移
npx prisma migrate deploy # 部署迁移
npx prisma generate # 生成客户端
npx prisma studio # 可视化数据库管理
3. TypeORM 实战
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, Repository } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({ unique: true })
email: string;
@Column({ nullable: true })
name: string;
@OneToMany(() => Post, post => post.author)
posts: Post[];
}
// Repository 模式
const userRepo = dataSource.getRepository(User);
// 查询
const user = await userRepo.findOne({
where: { email: 'alice@example.com' },
relations: ['posts']
});
// 原生 SQL
const users = await userRepo.query('SELECT * FROM users WHERE age > $1', [18]);
4. Mongoose 实战
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
email: { type: String, required: true, unique: true },
name: String,
age: { type: Number, min: 0 },
tags: [String],
metadata: {
loginCount: { type: Number, default: 0 },
lastLogin: Date
}
}, { timestamps: true });
// 索引
userSchema.index({ email: 1 });
userSchema.index({ createdAt: -1 });
const User = mongoose.model('User', userSchema);
// CRUD
const user = await User.create({ email: 'test@example.com', name: 'Test' });
const users = await User.find({ age: { $gte: 18 } })
.sort({ createdAt: -1 })
.limit(10)
.select('email name');
// 聚合
const stats = await User.aggregate([
{ $match: { age: { $exists: true } } },
{ $group: { _id: '$tags', count: { $sum: 1 }, avgAge: { $avg: '$age' } } }
]);
延伸阅读
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。