우선 이 내용을 기존과 겹치면 오히려 헷갈릴 수 있기 때문에 깔금하게 새로운 프로젝트를 만들고 시작합니다.
nest new 프로젝트 이름
터미널창에서 위 키워드를 입력해서 새로운 프로젝트를 만들어줍니다.
services:
postgres:
image: postgres:15
restart: always
volumes:
- ./postgres-data:/var/lib/postgresql/data
ports:
- "5432:5432"
environment:
POSTGRES_USER: postgres2
POSTGRES_PASSWORD: 패스워어어어어어드
POSTGRES_DB: typeormstudy
도커파일도 새롭게 만들어준 후
postgres-data 라는 폴더도 만들어줍니다.
이후엔 미리 설치된 도커파일 다시 실행시켜놓고
터미널창에서 docker-compose up
을 입력해서 다시 도커로 db 연결까지 잘 마무리 해 놓고 다시 시작을 해보겠습니다.
이제 app 모듈에서 db 설정도 작성해줍니다.
src/app.module.ts
@Module({
imports: [
TypeOrmModule.forFeature([
UserModel
]),
TypeOrmModule.forRoot({
type: 'postgres',
host: '127.0.0.1',
port: 5432,
username: 'postgres2',
password: '비밀번호오오오옹',
database: 'typeormstudy',
entities: [
UserModel,
],
synchronize: true,
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
src/entity/user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, PrimaryColumn, CreateDateColumn, UpdateDateColumn, VersionColumn, Generated } from 'typeorm';
@Entity()
export class UserModel {
/**
* @PrimaryGeneratedColumn()
* - PrimaryColumn 을 자동적으로 생성해주겠다는 의미가 있습니다.
*
*
* @PrimaryColumn()
* - 자동생성이 빠진 모든 테이블에 기본으로 존재해야 하는 칼럼을 의미합니다.
* - 자동으로 생성되지 않기 때문에 반드시 직접 넣어줘야 합니다
*
*
* @PrimaryGeneratedColumn(uuid)
* - PrimaryGeneratedColumn 의 값을 uuid값으로 생성해줍니다.
* ex) 0243c788-6f44-4cf4-8fdc-b387cf335342
*
*
* @CreateDateColumn()
* - 생성된 날짜와 시간을 자동으로 생성해줍니다.
*
*
* @UpdateDateColumn()
* - 업데이트 된 시간을 자동으로 생성해줍니다.
*
* @VersionColumn()
* - 데이터가 업데이트 될때마다 1씩 올라간다.
* - 처음 생성값은 1이고 정확히 말하면 save() 함수가 몇번 불렸는지를 기억하는 함수이다.
*
*
* @Generated(increment)
* - PrimaryColumn은 아니지만 그냥 1부터 1씩 증가한다
* - 사용할때에는 반드시 @Column() 과 같이 사용해줘야 한다.
*/
@PrimaryGeneratedColumn()
id: number;
// 제목
@Column()
title: string;
// 데이터 생성일자
@CreateDateColumn()
createdAt: Date;
// 데이터 업데이트 일자
@UpdateDateColumn()
updateAt: Date;
// 데이터가 변경될때마다 횟수를 카운팅
@VersionColumn()
version: number;
@Column()
@Generated('uuid')
additionalId: string;
}
유저정보로 사용될 엔티티도 생성해줍니다.
src 폴더에서 entity 라는 폴더를 생성후 그 폴더에서 다시 user.entity.ts 라는 파일을 생성해주고 뒤 코드 내용을 입력해줍니다.
주석으로 적힌 내용을 다시 짚어보면서 설명을 하자면
자주 사용될 혹은 알고있으면 좋을 칼럼들은 다음과 같습니다.
@PrimaryGeneratedColumn()
PrimaryColumn 을 자동적으로 생성해주겠다는 의미가 있습니다
@PrimaryGeneratedColumn(uuid)
PrimaryGeneratedColumn 의 값을 uuid값으로 생성해줍니다.
ex) 0243c788-6f44-4cf4-8fdc-b387cf335342
@CreateDateColumn()
생성된 날짜와 시간을 자동으로 생성해줍니다.
이제 위 엔티티를 실제로 사용해보기 위해 컨트롤러 에서 간단한 api 들을 만들어보겠습니다.
import { Controller, Get, Post,Patch, Param } from '@nestjs/common';
import { UserModel } from './entity/user.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { retry } from 'rxjs';
@Controller()
export class AppController {
constructor(
@InjectRepository(UserModel)
private readonly userRepository: Repository<UserModel>
) {}
@Post('users')
postUser() {
return this.userRepository.save({
title: 'test title'
});
}
@Get('users')
getUsers() {
return this.userRepository.find();
}
@Patch('users/:id')
async patchUser(
@Param('id') id:string
){
const user = await this.userRepository.findOne({
where:{
id:parseInt(id),
}
});
return this.userRepository.save({
...user,
title: user.title +'_+1',
})
}
}
거의 대분의 값을 이미 엔티티를 생성하면서 만들어지는게 많고 실제 값이 어떻게 나오는지를 테스트하기 위함이기 때문에 간단하게 작성을 해보았습니다.
title 값은 test title 로 고정하고
id 값
변경되는것은 version 이나
이제 이 내용을 토대로 포스트맨을 실행해보겠습니다
post 요청 사진입니다
사진상에서는 테스트로 여러번 만들어논후 캡쳐한거라 id 값이 3으로 나오고 있습니다.
그 외에 나머지 값들도 생각한대로 잘 나오는것을 볼 수 있습니다.
마찬가지로 get 요청 역시 잘되는것을 볼 수 있습니다.
patch 요청 사진 입니다.
2번 id 값의 내용을 수정하였고 수정할때마다 변경되기로한 version 값과 title의 +1 이 잘 나오는것도 확인할 수 있습니다.
column 은 보통 실제 테이블의 칼럼과 작성한 값을 매핑이 되는데 보통은 타입스크립트가 자동으로 유추를 하는데요,
일반적으로는 아래 예시와 같이 타입을 작성해서 지정해주는게 좋습니다.
// 제목
@Column({
type: 'varchar'
})
title: string;
자동완성으로 타입을 찾기도 편하게 되어 있습니다.
이제 여기서 작성할 수 있는것들을 몇가지 예시로 작성해보자면 다음과 같습니다.
src/entity/user.entity.ts
// 제목
@Column({
// 보통 자동으로 유추
name: 'title',
type: 'varchar',
// 값의 길이를 지정한다. 최대 300
length:100,
// null 을 허용하는지
nullable: true,
// 타이틀값이 변경이 가능한지
update:true,
// 이 칼럼의 값을 보이게 할건지 안할건지
select:false
// 아무런 값도 입력하지 않았을대에 주어지는 기본값
default: 'default value'
// 칼럼중에서 유일무이한 값이 되어야 하는지
unique: false,
})
title: string;
위 내용들의 설명은 주석과 같습니다.
이렇게 변경후 테스트로 다시 포스트맨을 실행해보겠습니다.
select를 예시로 먼저 더 보여드리도록 하겠습니다.
slect 값을 false 로 변경했을때에는 get 요청을 해도 값이 안나오는것을 볼 수 있습니다.
여기서 원래대로 false 를 true 로 변경하면 기존과 동일하게 나오게 하겠지만 엔티티파일에서가 아닌 컨트롤러에서도 변경이 가능한데요,
@Get('users')
getUsers() {
return this.userRepository.find({
select:{
title:true,
}
});
}
컨트롤러에 있는 get 요청 코드를 추가하면 select 만 보게 하는것도 가능합니다.
default 같은경우는 아무런 값도 입력하지 않았을때에 나오는 값을 의미합니다.
@Post('users')
postUser() {
return this.userRepository.save({
// title: 'test title'
});
}
포스트요청에서 기본으로 작성되었던 title 값을 주석처리하였고, 위에서 이미 null 값을 허용해놨기 때문에 post 요청이 실행을 잘될텐데요, 이때 입력될 값이 없었기 때문에 defalut 에 미리 입력해놓은 값으로 생성이 됩니다.
마지막으로 unique 입니다
유니크값은 primary 값이 아닌 값중에서 절대 겹치지 않아야될 유일무이한 값으로 지정해야할때 사용할 수 있습니다.
대표적인 예로 회원가입시 이메일 값을 unique 값으로 세팅할 수도 있겠습니다.
우선 기존에 있던 자료를 전부 지우고 새롭게 post요청을 해보면 다음과 같은 오류가 나오는데요,
이게 유니크 때문에 발생한 에러입니다.