Post

[Nest.js 학습일기] Relationship Option

[Nest.js 학습일기] Relationship Option

Relationship Option

OneToOne부터 ManyToMany까지 모든 관계에서 사용 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@OneToOne(() => ProfileModel, (profile) => profile.user, {
  // find() 실행할 때 항상 같이 가져올 relation
  // 즉, controller에서 relation을 정의하지 않아도 relation 설정을 하고 가져온단 말임.
  eager: true,
  // 저장할 때 relation을 한번에 같이 저장 가능
  cascade: true,
  // null이 가능한지
  nullable: true,
  // 관계가 삭제되었을 때
  // no action => 아무것도 안함
  // CASCADE =>  참조하는 row도 같이 삭제
  // SET NULl => 참조 id를 null값으로
  // SET DEFAULT => 기본 세팅으로 변경 (테이블의 기본 세팅)
  // RESTRICT => 참조하고 있는 row가 있는 경우 참조당하는 row 삭제 불가
  onDelete: 'CASCADE'
})
profile: ProfileModel;

eagertrue로 한다면

1
2
3
4
5
6
7
8
9
@Get('users')
getUsers() {
  return this.userRepository.find({
    // relations: {
    //   profile: true,
    //   posts: true,
    // }
  });
}

이처럼 relationship을 따로 지정하지 않아도 controller에서 find() 실행 시 relation을 확인할 수 있다.

cascadetrue로 한다면

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  @Post('user/profile')
    async createUserAndProfile() {
    const user = await this.userRepository.save({
      email: 'testmail@gmail.com',
      profile: {
        profileImg: 'abc.jpg'
      }
    })
  // const profile = await this.profileRepository.save({
  //   profileImg: 'abc.jpg',
  //   user,
  // })
  return user;
}

이처럼 profile을 한번에 담아서 (relation관계) 저장하는 행위 등이 가능하다.

nullable,onDelete의 예시는 최상단 확인.

Find Option

find를 사용할 때 사용할 수 있는 옵션들

select

정의된 프로퍼티만 가져오도록 할 수 있다.

1
2
3
4
5
6
7
8
9
// codes ...
// select 사용 예시
select: {
  id: true,
    createdAt: true,
    updatedAt: true,
    version: true,
},
// codes ...

where

조건문이라 생각하면 된다. && (and)로 조건을 걸고 싶으면 연속적으로 작성하면 된다.

where(and)

1
2
3
4
5
6
7
// codes ...
// 연속작성 => and
where: {
  id: 1,
  version: 3
}
// codes...

where(or)

1
2
3
4
5
6
7
8
9
10
11
// codes...
// 리스트로 작성 => or
where: [
  {
    id: 1,
  },
  {
    version: 1,
  }
]
// codes ...

where 심화

typeORM에서 다음과 같은 것들을 import하여 아래 예시처럼 조건을 걸 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Get('users')
getUsers() {
  return this.userRepository.find({
    where: {
      // 1이 아닌 경우를 가져오기
      // id: Not(1),
      
      // 미만 이하 이상 초과 동일
      // id: LessThan(20),
      // id: LessThanOrEqual(20),
      // id: MoreThanOrEqual(20),
      // id: MoreThan(20),
      // id: Equal(20),

      // 유사값
      // email: Like('%0%')
      // 유사값 - 대소문자 구별 x
      // email: ILike('%GMail%')
      
      // 사이값
      // id: Between(10, 15)
      
      // 해당되는 여러개의 값
      // id: In([1,3,5,7])
      
      // null인 경우를 가져옴
      // id: IsNull()
    }
  });
}

relations

관계를 가져온다.

1
2
3
relations: {
      profile: true,
    },

select와 where에 조건을 걸어 relation에 다양한 조작이 가능하다.

order

오름차순 (ASC) 내림차순 (DESC)로 정렬 가능하다.

1
2
3
4
order: {
      id: "ASC"
      // id: "DESC"
    },

skip & take

skip은 처음 몇개를 넘어갈 것이냐, take는 몇개를 취할 것이냐를 의미한다.

두개를 동시에 사용하여 index 몇부터 몇을 가져온다 등의 조작이 가능하다.

1
2
3
4
5
// 처음 몇개를 넘어갈것이냐.
skip: 0,
// 그래서 몇개를 가져올 것이냐 (skip과 사용도 높음)
// 0이 기본 값 (0이면 모든 값 가져옴)
take: 2,

메서드 종류

find, create, preload, findAndCount 등 다양한 메서드가 존재한다. find는 상단에서 다루었으니 그 외의 매서드를 살펴보자.

create

save의 경우 객체를 생성하고 저장하는 과정까지 진행한다. 이와 달리 create는 객체를 생성하는 과정만 진행하는 메서드이다.

1
2
3
const user1 = this.userRepository.create({
    email: 'testmail@gmail.com',
  });

preload

입력된 값을 기반으로 DB에 있는 데이터를 불러오고 새로 제공된 값들로 업데이트할 객체를 생성하는 메서드이다. find + create 정도로 이해하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// DB에 저장된 기존 데이터
{
  id: 100,
    email: 'old@gmail.com',
  name: 'John',
  age: 25
}

// preload 호출
const user = await userRepository.preload({
  id: 100,
  email: 'preload@gmail.com'
});

// 결과
{
  id: 100,
    email: 'preload@gmail.com', // 새로운 값으로 변경됨
  name: 'John',               // 기존 값 유지
  age: 25                     // 기존 값 유지
}

delete

1
2
3
4
await this.userRepository.delete({
    id: 2,
  })
  return user2

increment & decrement

일정 row의 값을 올리거나 내리는 문법

1
2
3
4
5
6
// 숫자 값을 올리기
// 어떤 조건에 해당하는 것의 'numb' Row를 1올리겠다!
// 숫자 내리기는 decrement 사용
await this.userRepository.increment({
  id: 1,
}, 'numb', 1)

count

조건에 부합하는 것들 카운트

1
2
3
4
5
6
// 개수세기
const count = await this.userRepository.count({
  where: {
    email: ILike('%0%')
  }
})

sum

1
2
3
4
5
// 합 구하기
const sum = await this.userRepository.sum('numb', {
    email: ILike('%0%')
})
return sum

average

1
2
3
4
5
// 평균 구하기
const average = await this.userRepository.average('numb', {
  id: LessThan(4)
})
return average

minimum & maximum

1
2
3
4
5
6
7
8
// 최소값/최대값
const min = await this.userRepository.minimum('numb', {
  id: LessThan(4),
})
const max = await this.userRepository.maximum('numb', {
  id: LessThan(4),
})
return [min, max]

findAndCount

리스트형태로 값을 반환하는데, [가져온 목록, 갯수] 꼴로 값을 반환한다. 이후 학습할 pagination에서 이를 활용한다.

1
2
3
4
5
6
7
8
// [가져온 목록, 갯수]를 가져옴
// pagination에서 활용
const userAndCount = await this.userRepository.findAndCount({
  take: 3,
})
// 3명의 유저 (take 조건) , user 전체인원 을 가져옴
return userAndCount
}
This post is licensed under CC BY 4.0 by the author.