repository.create() vs new xxEntity()

ansunny1170·2024년 12월 4일
0

Nest.js 시작하기

목록 보기
3/3

출처 chatGPT

@BeforeInsert()의 작동 시점

Q: BeforeInsert()는 save() 후에 실행되는 것인가?

•	아니요. BeforeInsert()는 save()를 호출한 후, 실제 INSERT SQL이 실행되기 직전에 실행됩니다.

Q: create()와 관계가 없나?

•	네. create()는 엔티티 객체를 메모리에만 생성하므로, @BeforeInsert()와는 관계가 없습니다.

아래 코드에서 1번에서 userId는 없고, 2번에서 userId는 있는 이유는?

const newUser = new UserEntity();
    newUser.name = name;
    newUser.nickname = await this.generateNickname();
    newUser.dateOfBirth = dateOfBirth;
    newUser.gender = gender;
    newUser.country = country;
    newUser.email = payload.emails[0].value;
    newUser.metadata = payload;

    const newUserEntity = this.userRepo.create(newUser);
    console.log('1. google user id: ', newUserEntity);
    await this.userRepo.save(newUserEntity);

    console.log('2. google user id: ', newUserEntity);
  1. this.userRepo.create(newUser)를 호출했을 때:
    • create()는 엔티티를 메모리에만 생성하므로, userId는 아직 설정되지 않습니다.
  2. await this.userRepo.save(newUserEntity)를 호출했을 때:
    • save()를 호출하면:
    1. TypeORM이 @BeforeInsert()를 실행합니다.
      • @BeforeInsert() 메서드에서 this.userId = generateEntityId()가 실행되어 userId가 설정됩니다.
    2. TypeORM이 INSERT SQL을 실행하여 데이터베이스에 엔티티를 저장합니다.
    3. save() 메서드가 종료되면, userId와 같은 값이 객체에 업데이트됩니다.

create()의 용도? 역할?

create()는 단순히 객체를 메모리에 생성하는 역할을 하기 때문에, 처음 보면 “굳이 필요한가?“라는 생각이 들 수 있습니다. 하지만 create()는 특정 상황에서 유용한 도구입니다. 아래에서 create()의 용도와 이를 활용할 수 있는 상황들을 정리해 보겠습니다.

1. create()의 주요 용도

1-1. 엔티티 생성 및 초기화

•	엔티티를 생성하면서 기본값이나 초기값을 세팅할 때 유용합니다.
•	예를 들어, 데이터베이스에 저장하기 전 임시적으로 객체를 다룰 때 사용합니다.
const user = this.userRepo.create({
  name: 'John Doe',
  email: 'john@example.com',
  nickname: 'RandomNick',
});
// 객체를 메모리에서 초기화했을 뿐, DB에는 저장되지 않음.

1-2. 데이터베이스에 저장하지 않고 작업할 때

•	데이터베이스와 상호작용하지 않아도 되는 작업에 사용합니다. 예를 들어:
•	데이터를 생성해서 응답으로 반환할 때.
•	테스트 데이터나 임시 데이터를 생성할 때.
const tempUser = this.userRepo.create({
  name: 'Temporary User',
  email: 'temp@example.com',
});
// 이 객체는 DB에 저장되지 않지만, 이후 응답으로 사용할 수 있음.
return tempUser;

1-3. save()와 분리된 단계적 처리

•	객체를 먼저 생성한 뒤, 필요한 추가 작업을 거쳐 최종적으로 save()로 데이터베이스에 저장합니다.
•	예를 들어, 데이터 생성 후 비동기 작업을 수행한 다음 저장할 때:
const user = this.userRepo.create({
  name: 'Alice',
  email: 'alice@example.com',
});
// 추가 처리
user.nickname = await this.generateNickname();
// 최종적으로 저장
await this.userRepo.save(user);

1-4. 복잡한 연관 관계를 가진 엔티티 생성

•	연관 관계를 가진 엔티티를 생성할 때 create()를 사용하면 엔티티 객체를 간단히 초기화할 수 있습니다.
•	데이터베이스에 직접 접근하지 않고 객체 간 관계를 설정할 때 유용합니다.
const reservation = this.reservationRepo.create({
  user: { userId: 'user_1234' }, // 관계를 가진 엔티티를 생성
  date: new Date(),
});
await this.reservationRepo.save(reservation);

2. create()와 save()의 조합

•	create()를 사용하면 객체 생성과 초기화를 분리하여 코드를 더 가독성 있게 유지할 수 있습니다.
•	단순히 데이터를 삽입하려면 save()만으로도 충분하지만, 객체 생성 → 추가 처리 → 저장의 과정을 거쳐야 한다면 create()가 유용합니다.

3. 언제 create()가 필요 없는가?

•	간단히 데이터를 데이터베이스에 저장하려는 경우, create() 없이 save()만 사용하는 것이 더 직관적이고 간결합니다.
await this.userRepo.save({
  name: 'John Doe',
  email: 'john@example.com',
  nickname: 'RandomNick',
});

4. 요약

•	create()는 메모리에서 객체를 생성하고 초기화할 때 사용하며, 데이터베이스와 상호작용하지 않습니다.
•	복잡한 로직을 작성하거나 객체를 먼저 생성한 뒤 후처리를 거쳐 저장해야 할 때 유용합니다.
•	단순 삽입 작업만 필요하다면 save()로 충분합니다.

따라서, create()와 save()는 상황에 따라 함께 사용할 수도, 독립적으로 사용할 수도 있습니다. 🚀

create() vs new userEntity() 방식 차이

create()와 new UserEntity()는 모두 엔티티 객체를 생성하는 데 사용되지만, 동작 방식과 용도가 약간 다릅니다. 아래에서 차이를 정리해 보겠습니다.

1. create()

TypeORM의 Repository에서 제공하는 메서드로, 엔티티를 초기화하는 데 사용됩니다.

특징

  1. 엔티티 정의에 따라 기본값 초기화
    • @BeforeInsert 같은 데코레이터가 붙은 메서드는 호출되지 않지만, 기본값이 있는 컬럼은 자동으로 채워집니다.
  2. 객체를 메모리에 생성
    • 데이터베이스에 접근하지 않고 메모리에서 객체만 생성합니다.
  3. 관계 설정이 더 편리
    • 연관 관계를 가진 엔티티를 생성하거나 초기화할 때 유용합니다.
    • 예를 들어, 관계를 가진 엔티티를 간단히 참조로 연결할 수 있습니다.
const user = this.userRepo.create({
  name: 'John Doe',
  email: 'john@example.com',
  nickname: 'Happy_pudding_0001',
});
  1. 추가 처리 후 저장 가능
    • save()를 통해 데이터베이스에 저장하기 전 객체를 수정할 수 있습니다.

2. new UserEntity()

JavaScript/TypeScript의 표준 객체 생성 방법으로, 엔티티 클래스의 인스턴스를 직접 생성합니다.

특징

  1. TypeORM의 Repository와 무관
    • Repository를 사용하지 않고 TypeScript 클래스 자체를 사용하여 엔티티를 직접 생성합니다.
    • TypeORM의 추가 기능은 동작하지 않습니다(예: 기본값 자동 설정, 관계 초기화).
  2. 완전 수동으로 모든 값 설정
    • 엔티티의 모든 필드를 직접 설정해야 합니다.
const user = new UserEntity();
user.name = 'John Doe';
user.email = 'john@example.com';
user.nickname = 'Happy_pudding_0001';
  1. 간단한 객체 초기화
    • 간단히 객체를 생성하거나 TypeORM을 사용하지 않는 테스트 환경에서 유용합니다.
  2. 연관 관계 설정 불편
    • RelationId나 관계 엔티티를 직접 설정해야 합니다.

3. 주요 차이점

특징create()new UserEntity()
TypeORM 의존성TypeORM의 Repository 메서드TypeORM 없이도 사용 가능
기본값 초기화기본값을 자동으로 채움기본값 수동으로 설정
데이터베이스 관계관계 엔티티를 쉽게 설정 가능관계 설정이 번거로움
유효성 검사 및 변환DTO 매핑 시 유효성 검사 및 변환 지원직접 설정 필요
사용 사례TypeORM과 함께 사용하며 저장 전 객체 수정 가능TypeORM 없이 독립적으로 객체를 생성하거나 테스트 시 사용

4. 어떤 상황에서 어떤 것을 사용해야 할까?

• TypeORM과 함께 사용할 때:
• create()를 사용하여 엔티티를 생성하고 초기화하는 것이 좋습니다. 특히 기본값 초기화와 관계 설정이 유용합니다.
• 단순 객체 생성이 필요한 경우:
• new UserEntity()를 사용하여 객체를 직접 생성하고 수동으로 값을 설정할 수 있습니다.
• 테스트 목적으로 사용할 때:
• 데이터베이스를 사용하지 않고 독립적인 객체가 필요하다면 new UserEntity()를 사용하는 것이 적합합니다.

결론

•	create()는 TypeORM의 기능을 활용하며 엔티티 생성 과정을 간소화합니다.
•	new UserEntity()는 TypeORM과 무관하게 객체를 생성하는 기본적인 방법으로, 더 많은 수작업이 필요합니다.

따라서, TypeORM과 함께 동작하는 환경에서는 대부분 create()를 사용하는 것이 더 직관적이고 효율적입니다.

profile
공정 설비 개발/연구원에서 웹 서비스 개발자로 경력 이전하였습니다. Node.js 백엔드 기반 풀스택 개발자를 목표로 하고 있습니다.

0개의 댓글