NestJS数据库集成 (Database Integration)
学习目标
- 理解数据库集成在NestJS中的作用和地位
- 掌握TypeORM的基本使用方法
- 学会使用Prisma进行数据库操作
- 理解MongoDB的集成方式
- 能够实现基本的数据库操作(增删改查)
核心知识点
1. 数据库集成概述
NestJS支持多种数据库集成方式,主要包括:
- TypeORM:一个功能强大的ORM库,支持多种关系型数据库
- Prisma:一个现代的ORM工具,提供类型安全的数据库访问
- MongoDB:通过Mongoose或MongoDB驱动进行集成
- 原生驱动:直接使用数据库的原生驱动
选择合适的数据库集成方式取决于项目需求、团队熟悉度和性能要求。
2. TypeORM集成
TypeORM是NestJS官方推荐的ORM库,它支持多种关系型数据库,如MySQL、PostgreSQL、SQLite等。
安装依赖
npm install @nestjs/typeorm typeorm mysql2
# 或
npm install @nestjs/typeorm typeorm pg
# 或
npm install @nestjs/typeorm typeorm sqlite3配置TypeORM
在根模块中配置TypeORM:
// app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersModule } from './users/users.module';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'password',
database: 'nestjs-db',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true, // 开发环境使用,生产环境应关闭
}),
UsersModule,
],
})
export class AppModule {}创建实体
创建一个用户实体:
// users/entities/user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
email: string;
@Column()
password: string;
@Column({ default: () => 'CURRENT_TIMESTAMP' })
created_at: Date;
@Column({ default: () => 'CURRENT_TIMESTAMP' })
updated_at: Date;
}创建用户模块
// users/users.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService],
})
export class UsersModule {}创建用户服务
// users/users.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private usersRepository: Repository<User>,
) {}
async create(createUserDto: CreateUserDto): Promise<User> {
const user = this.usersRepository.create(createUserDto);
return await this.usersRepository.save(user);
}
async findAll(): Promise<User[]> {
return await this.usersRepository.find();
}
async findOne(id: number): Promise<User> {
const user = await this.usersRepository.findOne({ where: { id } });
if (!user) {
throw new NotFoundException(`User with id ${id} not found`);
}
return user;
}
async update(id: number, updateUserDto: UpdateUserDto): Promise<User> {
const user = await this.findOne(id);
Object.assign(user, updateUserDto);
return await this.usersRepository.save(user);
}
async remove(id: number): Promise<void> {
const result = await this.usersRepository.delete(id);
if (result.affected === 0) {
throw new NotFoundException(`User with id ${id} not found`);
}
}
}3. Prisma集成
Prisma是一个现代的ORM工具,提供类型安全的数据库访问,支持PostgreSQL、MySQL、SQLite等多种数据库。
安装依赖
npm install prisma @prisma/client
npx prisma init配置Prisma
编辑prisma/schema.prisma文件:
// prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
name String
email String @unique
password String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}生成Prisma客户端
npx prisma migrate dev --name init
npx prisma generate创建Prisma服务
// prisma.service.ts
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
async onModuleInit() {
await this.$connect();
}
async onModuleDestroy() {
await this.$disconnect();
}
}注册Prisma服务
// app.module.ts
import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { UsersModule } from './users/users.module';
@Module({
imports: [UsersModule],
providers: [PrismaService],
exports: [PrismaService],
})
export class AppModule {}使用Prisma服务
// users/users.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../prisma.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
@Injectable()
export class UsersService {
constructor(private prisma: PrismaService) {}
async create(createUserDto: CreateUserDto) {
return this.prisma.user.create({
data: createUserDto,
});
}
async findAll() {
return this.prisma.user.findMany();
}
async findOne(id: number) {
const user = await this.prisma.user.findUnique({
where: { id },
});
if (!user) {
throw new NotFoundException(`User with id ${id} not found`);
}
return user;
}
async update(id: number, updateUserDto: UpdateUserDto) {
return this.prisma.user.update({
where: { id },
data: updateUserDto,
});
}
async remove(id: number) {
try {
return await this.prisma.user.delete({
where: { id },
});
} catch (error) {
throw new NotFoundException(`User with id ${id} not found`);
}
}
}4. MongoDB集成
NestJS支持通过Mongoose或MongoDB驱动集成MongoDB。
安装依赖
npm install @nestjs/mongoose mongoose配置MongoDB
在根模块中配置MongoDB:
// app.module.ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { UsersModule } from './users/users.module';
@Module({
imports: [
MongooseModule.forRoot('mongodb://localhost:27017/nestjs-db'),
UsersModule,
],
})
export class AppModule {}创建模式
创建一个用户模式:
// users/schemas/user.schema.ts
import { Schema } from 'mongoose';
export const UserSchema = new Schema({
name: String,
email: String,
password: String,
createdAt: { type: Date, default: Date.now },
updatedAt: { type: Date, default: Date.now },
});注册模式
// users/users.module.ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { UserSchema } from './schemas/user.schema';
@Module({
imports: [MongooseModule.forFeature([{ name: 'User', schema: UserSchema }])],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService],
})
export class UsersModule {}使用MongoDB
// users/users.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { User } from './interfaces/user.interface';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
@Injectable()
export class UsersService {
constructor(@InjectModel('User') private userModel: Model<User>) {}
async create(createUserDto: CreateUserDto): Promise<User> {
const createdUser = new this.userModel(createUserDto);
return createdUser.save();
}
async findAll(): Promise<User[]> {
return this.userModel.find().exec();
}
async findOne(id: string): Promise<User> {
const user = await this.userModel.findById(id).exec();
if (!user) {
throw new NotFoundException(`User with id ${id} not found`);
}
return user;
}
async update(id: string, updateUserDto: UpdateUserDto): Promise<User> {
const user = await this.userModel.findByIdAndUpdate(id, updateUserDto, { new: true }).exec();
if (!user) {
throw new NotFoundException(`User with id ${id} not found`);
}
return user;
}
async remove(id: string): Promise<void> {
const result = await this.userModel.findByIdAndDelete(id).exec();
if (!result) {
throw new NotFoundException(`User with id ${id} not found`);
}
}
}5. 数据库连接配置
使用环境变量
在实际应用中,应该使用环境变量来配置数据库连接:
// app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
ConfigModule.forRoot(),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
type: 'mysql',
host: configService.get('DATABASE_HOST'),
port: +configService.get('DATABASE_PORT'),
username: configService.get('DATABASE_USERNAME'),
password: configService.get('DATABASE_PASSWORD'),
database: configService.get('DATABASE_NAME'),
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: configService.get('DATABASE_SYNCHRONIZE') === 'true',
}),
inject: [ConfigService],
}),
],
})
export class AppModule {}连接池配置
对于生产环境,应该配置数据库连接池:
// app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
// 基本配置
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'password',
database: 'nestjs-db',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: false,
// 连接池配置
poolSize: 10,
connectorPackage: 'mysql2',
extra: {
authPlugin: 'mysql_native_password',
},
}),
],
})
export class AppModule {}6. 实体关系
一对一关系
// entities/user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, OneToOne, JoinColumn } from 'typeorm';
import { Profile } from './profile.entity';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToOne(() => Profile, profile => profile.user, { cascade: true })
@JoinColumn()
profile: Profile;
}
// entities/profile.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, OneToOne } from 'typeorm';
import { User } from './user.entity';
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number;
@Column()
bio: string;
@OneToOne(() => User, user => user.profile)
user: User;
}一对多关系
// entities/user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';
import { Post } from './post.entity';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(() => Post, post => post.user)
posts: Post[];
}
// entities/post.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne } from 'typeorm';
import { User } from './user.entity';
@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@ManyToOne(() => User, user => user.posts)
user: User;
}多对多关系
// entities/user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, ManyToMany, JoinTable } from 'typeorm';
import { Role } from './role.entity';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToMany(() => Role)
@JoinTable()
roles: Role[];
}
// entities/role.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, ManyToMany } from 'typeorm';
import { User } from './user.entity';
@Entity()
export class Role {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToMany(() => User)
users: User[];
}7. 事务管理
TypeORM事务
// users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Transaction, TransactionManager, EntityManager } from 'typeorm';
import { User } from './entities/user.entity';
import { CreateUserDto } from './dto/create-user.dto';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private usersRepository: Repository<User>,
) {}
@Transaction()
async createWithTransaction(
createUserDto: CreateUserDto,
@TransactionManager() manager?: EntityManager,
): Promise<User> {
const user = manager.create(User, createUserDto);
return await manager.save(user);
}
}Prisma事务
// users.service.ts
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma.service';
import { CreateUserDto } from './dto/create-user.dto';
@Injectable()
export class UsersService {
constructor(private prisma: PrismaService) {}
async createWithTransaction(createUserDto: CreateUserDto) {
return this.prisma.$transaction(async (prisma) => {
const user = await prisma.user.create({
data: createUserDto,
});
// 可以在这里执行其他数据库操作
return user;
});
}
}8. 数据库迁移
TypeORM迁移
# 生成迁移
npx typeorm migration:generate -d src/data-source.ts src/migrations/CreateUsersTable
# 运行迁移
npx typeorm migration:run -d src/data-source.ts
# 回滚迁移
npx typeorm migration:revert -d src/data-source.tsPrisma迁移
# 创建迁移
npx prisma migrate dev --name add-users-table
# 应用迁移到生产环境
npx prisma migrate deploy
# 查看迁移状态
npx prisma migrate status9. 性能优化
- 使用索引:为频繁查询的列添加索引
- 使用分页:避免一次性查询大量数据
- 使用查询构建器:优化复杂查询
- 使用缓存:缓存频繁访问的数据
- 避免N+1查询:使用预加载(eager loading)
10. 最佳实践
- 使用环境变量:存储数据库连接信息
- 分离配置:将数据库配置与业务逻辑分离
- 使用事务:确保数据一致性
- 错误处理:妥善处理数据库错误
- 日志记录:记录数据库操作日志
- 定期备份:定期备份数据库
实践案例分析
案例:用户管理系统
需求分析
我们需要创建一个用户管理系统,包括:
- 用户的增删改查操作
- 使用TypeORM进行数据库集成
- 支持用户与角色的多对多关系
- 实现基本的事务管理
- 提供类型安全的数据库访问
实现步骤
- 安装必要的依赖
- 配置数据库连接
- 创建实体
- 实现服务层
- 创建控制器
- 测试系统功能
代码实现
1. 安装依赖
npm install @nestjs/typeorm typeorm pg2. 配置数据库连接
// app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersModule } from './users/users.module';
import { RolesModule } from './roles/roles.module';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'password',
database: 'nestjs-db',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true,
}),
UsersModule,
RolesModule,
],
})
export class AppModule {}3. 创建实体
// users/entities/user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, ManyToMany, JoinTable } from 'typeorm';
import { Role } from '../../roles/entities/role.entity';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column({ unique: true })
email: string;
@Column()
password: string;
@Column({ default: () => 'CURRENT_TIMESTAMP' })
createdAt: Date;
@Column({ default: () => 'CURRENT_TIMESTAMP' })
updatedAt: Date;
@ManyToMany(() => Role)
@JoinTable()
roles: Role[];
}// roles/entities/role.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, ManyToMany } from 'typeorm';
import { User } from '../../users/entities/user.entity';
@Entity()
export class Role {
@PrimaryGeneratedColumn()
id: number;
@Column({ unique: true })
name: string;
@ManyToMany(() => User)
users: User[];
}4. 创建DTO
// users/dto/create-user.dto.ts
export class CreateUserDto {
name: string;
email: string;
password: string;
roleIds?: number[];
}
// users/dto/update-user.dto.ts
export class UpdateUserDto {
name?: string;
email?: string;
password?: string;
roleIds?: number[];
}// roles/dto/create-role.dto.ts
export class CreateRoleDto {
name: string;
}
// roles/dto/update-role.dto.ts
export class UpdateRoleDto {
name?: string;
}5. 实现服务层
// roles/roles.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Role } from './entities/role.entity';
import { CreateRoleDto } from './dto/create-role.dto';
import { UpdateRoleDto } from './dto/update-role.dto';
@Injectable()
export class RolesService {
constructor(
@InjectRepository(Role)
private rolesRepository: Repository<Role>,
) {}
async create(createRoleDto: CreateRoleDto): Promise<Role> {
const role = this.rolesRepository.create(createRoleDto);
return await this.rolesRepository.save(role);
}
async findAll(): Promise<Role[]> {
return await this.rolesRepository.find();
}
async findOne(id: number): Promise<Role> {
return await this.rolesRepository.findOne({ where: { id } });
}
async update(id: number, updateRoleDto: UpdateRoleDto): Promise<Role> {
const role = await this.rolesRepository.findOne({ where: { id } });
Object.assign(role, updateRoleDto);
return await this.rolesRepository.save(role);
}
async remove(id: number): Promise<void> {
await this.rolesRepository.delete(id);
}
}// users/users.service.ts
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Transaction, TransactionManager, EntityManager } from 'typeorm';
import { User } from './entities/user.entity';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { RolesService } from '../roles/roles.service';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private usersRepository: Repository<User>,
private rolesService: RolesService,
) {}
@Transaction()
async create(
createUserDto: CreateUserDto,
@TransactionManager() manager?: EntityManager,
): Promise<User> {
const user = manager.create(User, {
name: createUserDto.name,
email: createUserDto.email,
password: createUserDto.password,
});
const savedUser = await manager.save(user);
if (createUserDto.roleIds && createUserDto.roleIds.length > 0) {
const roles = await this.rolesService.findAll();
const userRoles = roles.filter(role => createUserDto.roleIds.includes(role.id));
savedUser.roles = userRoles;
await manager.save(savedUser);
}
return savedUser;
}
async findAll(): Promise<User[]> {
return await this.usersRepository.find({ relations: ['roles'] });
}
async findOne(id: number): Promise<User> {
const user = await this.usersRepository.findOne({ where: { id }, relations: ['roles'] });
if (!user) {
throw new NotFoundException(`User with id ${id} not found`);
}
return user;
}
@Transaction()
async update(
id: number,
updateUserDto: UpdateUserDto,
@TransactionManager() manager?: EntityManager,
): Promise<User> {
const user = await this.findOne(id);
Object.assign(user, {
name: updateUserDto.name,
email: updateUserDto.email,
password: updateUserDto.password,
});
if (updateUserDto.roleIds) {
const roles = await this.rolesService.findAll();
const userRoles = roles.filter(role => updateUserDto.roleIds.includes(role.id));
user.roles = userRoles;
}
return await manager.save(user);
}
async remove(id: number): Promise<void> {
const result = await this.usersRepository.delete(id);
if (result.affected === 0) {
throw new NotFoundException(`User with id ${id} not found`);
}
}
}6. 创建控制器
// roles/roles.controller.ts
import { Controller, Get, Post, Body, Put, Delete, Param } from '@nestjs/common';
import { RolesService } from './roles.service';
import { CreateRoleDto } from './dto/create-role.dto';
import { UpdateRoleDto } from './dto/update-role.dto';
import { Role } from './entities/role.entity';
@Controller('roles')
export class RolesController {
constructor(private rolesService: RolesService) {}
@Post()
create(@Body() createRoleDto: CreateRoleDto): Promise<Role> {
return this.rolesService.create(createRoleDto);
}
@Get()
findAll(): Promise<Role[]> {
return this.rolesService.findAll();
}
@Get(':id')
findOne(@Param('id') id: number): Promise<Role> {
return this.rolesService.findOne(id);
}
@Put(':id')
update(@Param('id') id: number, @Body() updateRoleDto: UpdateRoleDto): Promise<Role> {
return this.rolesService.update(id, updateRoleDto);
}
@Delete(':id')
remove(@Param('id') id: number): Promise<void> {
return this.rolesService.remove(id);
}
}// users/users.controller.ts
import { Controller, Get, Post, Body, Put, Delete, Param } from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { User } from './entities/user.entity';
@Controller('users')
export class UsersController {
constructor(private usersService: UsersService) {}
@Post()
create(@Body() createUserDto: CreateUserDto): Promise<User> {
return this.usersService.create(createUserDto);
}
@Get()
findAll(): Promise<User[]> {
return this.usersService.findAll();
}
@Get(':id')
findOne(@Param('id') id: number): Promise<User> {
return this.usersService.findOne(id);
}
@Put(':id')
update(@Param('id') id: number, @Body() updateUserDto: UpdateUserDto): Promise<User> {
return this.usersService.update(id, updateUserDto);
}
@Delete(':id')
remove(@Param('id') id: number): Promise<void> {
return this.usersService.remove(id);
}
}7. 创建模块
// roles/roles.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { RolesController } from './roles.controller';
import { RolesService } from './roles.service';
import { Role } from './entities/role.entity';
@Module({
imports: [TypeOrmModule.forFeature([Role])],
controllers: [RolesController],
providers: [RolesService],
exports: [RolesService],
})
export class RolesModule {}// users/users.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';
import { RolesModule } from '../roles/roles.module';
@Module({
imports: [TypeOrmModule.forFeature([User]), RolesModule],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService],
})
export class UsersModule {}测试结果
1. 创建角色
请求:
POST /roles
Content-Type: application/json
{
"name": "admin"
}响应:
{
"id": 1,
"name": "admin"
}2. 创建用户
请求:
POST /users
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com",
"password": "password123",
"roleIds": [1]
}响应:
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"password": "password123",
"createdAt": "2023-10-01T10:00:00.000Z",
"updatedAt": "2023-10-01T10:00:00.000Z",
"roles": [
{
"id": 1,
"name": "admin"
}
]
}3. 获取所有用户
请求:
GET /users响应:
[
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"password": "password123",
"createdAt": "2023-10-01T10:00:00.000Z",
"updatedAt": "2023-10-01T10:00:00.000Z",
"roles": [
{
"id": 1,
"name": "admin"
}
]
}
]4. 更新用户
请求:
PUT /users/1
Content-Type: application/json
{
"name": "John Doe Updated",
"email": "john.updated@example.com"
}响应:
{
"id": 1,
"name": "John Doe Updated",
"email": "john.updated@example.com",
"password": "password123",
"createdAt": "2023-10-01T10:00:00.000Z",
"updatedAt": "2023-10-01T10:05:00.000Z",
"roles": [
{
"id": 1,
"name": "admin"
}
]
}5. 删除用户
请求:
DELETE /users/1响应:
204 No Content代码解析
数据库配置:
- 使用TypeOrmModule配置PostgreSQL数据库连接
- 设置自动同步实体到数据库(开发环境)
实体定义:
- 创建User和Role实体
- 定义多对多关系
- 使用装饰器定义字段属性
服务实现:
- 使用@InjectRepository注入Repository
- 实现CRUD操作
- 使用@Transaction装饰器实现事务管理
- 处理实体关系
控制器实现:
- 创建RESTful API端点
- 处理HTTP请求和响应
- 调用服务层方法
模块组织:
- 按功能划分模块
- 正确配置模块依赖
- 导出需要共享的服务
互动思考问题
思考:TypeORM、Prisma和MongoDB的区别是什么?它们各自的使用场景是什么?
讨论:在实际应用中,如何选择合适的数据库集成方式?需要考虑哪些因素?
实践:尝试使用Prisma实现一个博客系统,包括用户、文章和评论的CRUD操作。
挑战:如何实现数据库的读写分离,提高系统性能?
扩展:了解NestJS的
@nestjs/event-emitter模块,思考如何结合数据库操作实现事件驱动架构。
小结
本集我们学习了NestJS数据库集成的核心概念和使用方法,包括:
- 数据库集成的基本概念和重要性
- TypeORM的安装和配置
- Prisma的使用方法
- MongoDB的集成方式
- 实体定义和关系映射
- 事务管理
- 数据库迁移
- 性能优化和最佳实践
通过实践案例,我们创建了一个完整的用户管理系统,展示了如何使用TypeORM实现用户和角色的CRUD操作,以及如何处理它们之间的多对多关系。数据库集成是NestJS应用开发中的重要组成部分,选择合适的数据库集成方式可以提高开发效率和系统性能。
在下一集中,我们将学习NestJS的数据库关系与查询,了解如何实现更复杂的数据库操作和查询优化。