Integrating and Using Databases in NestJS
- 626Words
- 3Minutes
- 11 Jul, 2024
This article provides a detailed explanation of how to integrate and use relational and non-relational databases in a NestJS project, including database configuration, model design, and the implementation of complex queries.
Integrating Relational Databases
Configuring TypeORM
TypeORM is a powerful ORM tool that supports various relational databases. We will use MySQL as an example to demonstrate how to configure TypeORM.
- Install the necessary packages:
1npm install --save @nestjs/typeorm typeorm mysql2
- Configure TypeORM in
app.module.ts
:
1import { Module } from "@nestjs/common";2import { TypeOrmModule } from "@nestjs/typeorm";3import { UsersModule } from "./users/users.module";4
5@Module({6 imports: [7 TypeOrmModule.forRoot({8 type: "mysql",9 host: "localhost",10 port: 3306,11 username: "root",12 password: "password",13 database: "test",14 entities: [__dirname + "/**/*.entity{.ts,.js}"],15 synchronize: true,16 }),17 UsersModule,18 ],19})20export class AppModule {}
Designing Database Models
Create a User
entity to define the database model for users:
1import { Entity, Column, PrimaryGeneratedColumn } from "typeorm";2
3@Entity()4export class User {5 @PrimaryGeneratedColumn()6 id: number;7
8 @Column()9 name: string;10
11 @Column()12 email: string;13
14 @Column()15 password: string;16}
Performing Database Operations
Implement CRUD operations in users.service.ts
:
1import { Injectable } from "@nestjs/common";2import { InjectRepository } from "@nestjs/typeorm";3import { Repository } from "typeorm";4import { User } from "./user.entity";5
6@Injectable()7export class UsersService {8 constructor(9 @InjectRepository(User)10 private usersRepository: Repository<User>,11 ) {}12
13 findAll(): Promise<User[]> {14 return this.usersRepository.find();15 }16
17 findOne(id: number): Promise<User> {18 return this.usersRepository.findOne(id);19 }20
21 create(user: User): Promise<User> {22 return this.usersRepository.save(user);23 }24
25 async update(id: number, user: Partial<User>): Promise<void> {26 await this.usersRepository.update(id, user);27 }28
29 async remove(id: number): Promise<void> {30 await this.usersRepository.delete(id);31 }32}
Implementing Complex Queries
Implement complex queries in users.service.ts
:
1import { Injectable } from "@nestjs/common";2import { InjectRepository } from "@nestjs/typeorm";3import { Repository } from "typeorm";4import { User } from "./user.entity";5
6@Injectable()7export class UsersService {8 constructor(9 @InjectRepository(User)10 private usersRepository: Repository<User>,11 ) {}12
13 // Complex query example: Find users with a specific keyword14 async findUsersByKeyword(keyword: string): Promise<User[]> {15 return this.usersRepository16 .createQueryBuilder("user")17 .where("user.name LIKE :keyword OR user.email LIKE :keyword", {18 keyword: `%${keyword}%`,19 })20 .getMany();21 }22}
Integrating Non-Relational Databases
Configuring Mongoose
Mongoose is a popular ODM tool for MongoDB. We will demonstrate how to configure Mongoose.
- Install the necessary packages:
1npm install --save @nestjs/mongoose mongoose
- Configure Mongoose in
app.module.ts
:
1import { Module } from "@nestjs/common";2import { MongooseModule } from "@nestjs/mongoose";3import { UsersModule } from "./users/users.module";4
5@Module({6 imports: [MongooseModule.forRoot("mongodb://localhost/nest"), UsersModule],7})8export class AppModule {}
Designing Database Models
Create a User
model to define the database schema for users:
1import { Schema } from "mongoose";2
3export const UserSchema = new Schema({4 name: String,5 email: String,6 password: String,7});
Performing Database Operations
Implement CRUD operations in users.service.ts
:
1import { Injectable } from "@nestjs/common";2import { InjectModel } from "@nestjs/mongoose";3import { Model } from "mongoose";4import { User } from "./user.interface";5import { CreateUserDto } from "./create-user.dto";6
7@Injectable()8export class UsersService {9 constructor(@InjectModel("User") private readonly userModel: Model<User>) {}10
11 async findAll(): Promise<User[]> {12 return this.userModel.find().exec();13 }14
15 async findOne(id: string): Promise<User> {16 return this.userModel.findById(id).exec();17 }18
19 async create(createUserDto: CreateUserDto): Promise<User> {20 const createdUser = new this.userModel(createUserDto);21 return createdUser.save();22 }23
24 async update(id: string, user: Partial<User>): Promise<User> {25 return this.userModel.findByIdAndUpdate(id, user, { new: true }).exec();26 }27
28 async remove(id: string): Promise<User> {29 return this.userModel.findByIdAndRemove(id).exec();30 }31}
Implementing Complex Queries
Implement complex queries in users.service.ts
:
1import { Injectable } from "@nestjs.common";2import { InjectModel } from "@nestjs/mongoose";3import { Model } from "mongoose";4import { User } from "./user.interface";5
6@Injectable()7export class UsersService {8 constructor(@InjectModel("User") private readonly userModel: Model<User>) {}9
10 // Complex query example: Find users with a specific keyword11 async findUsersByKeyword(keyword: string): Promise<User[]> {12 return this.userModel13 .find({14 $or: [15 { name: new RegExp(keyword, "i") },16 { email: new RegExp(keyword, "i") },17 ],18 })19 .exec();20 }21}
Conclusion
This article provided a detailed explanation of how to integrate and use relational and non-relational databases in NestJS. Through specific configurations and code examples, we demonstrated how to use TypeORM and Mongoose for database operations, model design, and implementing complex queries. In actual development, choosing the right database and ORM/ODM tools is crucial for building efficient and scalable applications.