NestJS
typeORM
Nest提供@nestjs/typeorm
套件來做TypeORM互動,因為TypeORM為TS中目前最成熟的ORM套件,他是用TS所寫的,所以能和Nest框架完美搭配。
以下會以MySQL為範例:
首先安裝套件:
$ npm install --save @nestjs/typeorm typeorm mysql2
安裝完後,將TypeOrmModule
引入到AppModule
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'root',
database: 'test',
entities: [],
synchronize: true,
}),
],
})
export class AppModule {}
Setting synchronize: true
shouldn't be used in production - otherwise you can lose production data.
當上面完成後,TypeORM的DataSource
和EntityManager
物件就可以在整個專案使用,如下:
import { DataSource } from 'typeorm';
@Module({
imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
constructor(private dataSource: DataSource) {}
}
TypeORM 支援repository design pattern,所以各個entity都有其repository,這些repository可以從database data source取得。
以下建立User
Entity做示範:
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
firstName: string;
@Column()
lastName: string;
@Column({ default: true })
isActive: boolean;
}
為開始使用User
Entity,我們將其放入app.module內的forRoot() method的entities陣列內。
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './users/user.entity';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'root',
database: 'test',
entities: [User],
synchronize: true,
}),
],
})
export class AppModule {}
現在換看UsersModule
:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { User } from './user.entity';
@Module({
imports: [TypeOrmModule.forFeature([User])],
providers: [UsersService],
controllers: [UsersController],
})
export class UsersModule {}
** 以下方式與文件不同,而是將與資料庫互動的部分從service拆分出來為一個*.repository.ts,而後在service中注入repository進而拆分權責,以便維護。 **
/// 從這後開始修改
這個module使用forFeature()
來定義是哪個repositories被註冊在目前的scope,有了這個,我們就可以將UserRepository
使用@InjectRepository()
注入到UsersService
中,如下:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private usersRepository: Repository<User>,
) {}
findAll(): Promise<User[]> {
return this.usersRepository.find();
}
findOne(id: string): Promise<User> {
return this.usersRepository.findOneBy({ id });
}
async remove(id: string): Promise<void> {
await this.usersRepository.delete(id);
}
}
如果你想要在外部的module使用此repository,你一樣必須要到module這裡把import的TypeOrmModule.forFeature
再把他export:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
@Module({
imports: [TypeOrmModule.forFeature([User])],
exports: [TypeOrmModule]
})
export class UsersModule {}