# Nest.js에서 TypeORM을 연동시켜주기 위해 사용하는 모듈
$ npm install --save @nestjs/typeorm
# typeorm module
$ npm install --save typeorm
# install mysql
$ npm install --save mysql2
typeorm.config.ts
import { TypeOrmModuleOptions } from '@nestjs/typeorm/dist/interfaces/typeorm-options.interface';
import { Member } from './member/entities/member.entity';
export const typeORMConfig: TypeOrmModuleOptions = {
type: 'mysql',
host: '127.0.0.1',
port: 3306,
username: 'root',
password: '1234',
database: 'nestjs_tutorial',
entities: [Member],
synchronize: true,
};
synchronize
는 엔티티와 데이터베이스 테이블을 자동으로 동기화할지 여부를 지정합니다.
만약 현재 엔티티와 데이터베이스 간의 불일치가 존재하면 해당 테이블을 DROP 한 뒤 다시 생성합니다.
app.module.ts
@Module({
imports: [TypeOrmModule.forRoot(typeORMConfig), MemberModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
App Module
에 위에서 설정한 TypeORMConfig
를 연결해줍니다.
직접 entity, repository, service, controller 등 생성하는 방법도 있지만, cli를 통해 한번에 생성할 수 있습니다.
$ nest g resource [entity-name]
team.entity.ts
export class Team {}
team.service.ts
import { Injectable } from '@nestjs/common';
import { CreateTeamDto } from './dto/create-team.dto';
import { UpdateTeamDto } from './dto/update-team.dto';
@Injectable()
export class TeamService {
create(createTeamDto: CreateTeamDto) {
return 'This action adds a new team';
}
findAll() {
return `This action returns all team`;
}
findOne(id: number) {
return `This action returns a #${id} team`;
}
update(id: number, updateTeamDto: UpdateTeamDto) {
return `This action updates a #${id} team`;
}
remove(id: number) {
return `This action removes a #${id} team`;
}
}
team.controller.ts
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
import { TeamService } from './team.service';
import { CreateTeamDto } from './dto/create-team.dto';
import { UpdateTeamDto } from './dto/update-team.dto';
@Controller('team')
export class TeamController {
constructor(private readonly teamService: TeamService) {}
@Post()
create(@Body() createTeamDto: CreateTeamDto) {
return this.teamService.create(createTeamDto);
}
@Get()
findAll() {
return this.teamService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.teamService.findOne(+id);
}
@Patch(':id')
update(@Param('id') id: string, @Body() updateTeamDto: UpdateTeamDto) {
return this.teamService.update(+id, updateTeamDto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.teamService.remove(+id);
}
}
team.module.ts
import { Module } from '@nestjs/common';
import { TeamService } from './team.service';
import { TeamController } from './team.controller';
@Module({
controllers: [TeamController],
providers: [TeamService],
})
export class TeamModule {}
이런 식으로 기본적인 형태를 지닌 entity
, service
, controller
, module
이 생성됩니다.
이후 함수 안에 세부적인 로직만 넣으면 간단한 CRUD는 금방 구현할 수 있습니다.
@Entity
데코레이션을 통해 엔티티를 설정합니다.
이후 @Column
데코레이션들을 통해 Entity 칼럼들을 설정합니다.
@Entity({ name: 'member' })
export class Member {
@PrimaryGeneratedColumn({ name: 'member_id' })
id: number;
@Column({ length: 50 })
name: string;
@Column()
age: number;
@Column()
gender: boolean; //남자1, 여자0
@CreateDateColumn({ name: 'created_at' })
createdAt: Date;
@UpdateDateColumn({ name: 'updated_at' })
updatedAt: Date;
@DeleteDateColumn({ name: 'deleted_at' })
deletedAt?: Date;
}
이후 module
과 tyeporm.config.ts
에 해당 entity를 설정합니다.
app.module.ts
@Module({
imports: [TypeOrmModule.forRoot(typeORMConfig), MemberModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
typeorm.config.ts
import { TypeOrmModuleOptions } from '@nestjs/typeorm/dist/interfaces/typeorm-options.interface';
import { Member } from './member/entities/member.entity';
import { Team } from './team/entities/team.entity';
export const typeORMConfig: TypeOrmModuleOptions = {
type: 'mysql',
host: '127.0.0.1',
port: 3306,
username: 'root',
password: '1234',
database: 'nestjs_tutorial',
entities: [Member],
synchronize: true,
};
@InjectRepository
데코레이션을 통해 해당 엔티티의 Repository
의존성 주입합니다.
이후 Reposiotry
내부의 메서드를 이용하여 엔티티 CRUD 로직을 구현합니다.
@Injectable()
export class MemberService {
constructor(
@InjectRepository(Member) private memberRepository: Repository<Member>,
) {}
async create(createMemberDto: CreateMemberDto): Promise<Member> {
const newMember = this.memberRepository.create(createMemberDto);
return this.memberRepository.save(newMember);
}
async findAll(): Promise<Member[]> {
return await this.memberRepository.find();
}
async findOne(id: number): Promise<Member> {
const member = await this.memberRepository.findOne({ where: { id: id } });
if (!member) {
throw new NotFoundException('Member not found');
}
return member;
}
async update(id: number, updateMemberDto: UpdateMemberDto): Promise<Member> {
const updateResult = await this.memberRepository.update(
id,
updateMemberDto,
);
if (updateResult.affected === 0) {
throw new NotFoundException('Member not found');
}
return this.memberRepository.findOne({ where: { id: id } });
}
async remove(id: number) {
const deleteResult = await this.memberRepository.delete(id);
if (deleteResult.affected === 0) {
throw new NotFoundException('Member not found');
}
}
}
이때, 해당 service의 module
에 엔티티를 등록해야 Repository<Entity>
인식이 가능합니다.
member.module.ts
@Module({
imports: [TypeOrmModule.forFeature([Member])],
controllers: [MemberController],
providers: [MemberService],
})
export class MemberModule {}
다음과 같이 constructor
에 위에서 만든 service
객체를 의존성 주입합니다.
@Controller('members')
export class MemberController {
constructor(private readonly memberService: MemberService) {}
@Post()
create(@Body() createMemberDto: CreateMemberDto) {
return this.memberService.create(createMemberDto);
}
@Get()
findAll() {
return this.memberService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.memberService.findOne(+id);
}
@Patch(':id')
update(@Param('id') id: string, @Body() updateMemberDto: UpdateMemberDto) {
return this.memberService.update(+id, updateMemberDto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.memberService.remove(+id);
}
}