학습 키워드

  • TypeORM
  • Activate Record Pattern
  • BaseEntity

 

학습 정리

학습정리를 시작하면서 사실 공식문서를 읽으면 이해가 더 잘 될 것 같다. 아래 참고자료에 공식문서를 올려놨다. 참고해도 좋다.

 

Activate Record Pattern

공부하고 나니까 패턴 이름이 개념과 일치하지않는 것 같아서 이해하기가 어려웠다. 이름이 왜 이렇게 지어졌는지 뜻풀이를 해보았다.

Active: 데이터베이스 접근이 활성화 되어있다.

Record: 데이터베이스의 테이블에서 한 행

객체 자체가 데이터베이스 레코드와 1:1로 매핑되고, 그 객체가 스스로 데이터베이스 작업을 수행할 수 있는 "활성화된 상태"에 있기 때문에 Active Record라는 이름이 붙었다.

한마디로 정리하자면, Entity 클래스 내에서 Repository 접근 및 CRUD 작업을 할 수 있게 해주는 패턴이다.

 

Activate Record pattern 장점이 뭘까?

  • 데이터와 로직의 통합:
    • 활성화 기록 패턴에서는 데이터베이스 테이블의 레코드를 나타내는 객체가 데이터 관련 로직을 포함합니다. 예를 들어, 객체 내부에서 데이터를 조회하거나 저장하는 기능이 포함된다.
    • 엔티티 객체로 단순히 데이터의 구조만 정의하는 것이 아니라, 데이터베이스와의 상호작용을 위한 메서드들(save(), update(), delete())도 포함하고 있다. → EntityBase를 상속함으로써 가능하다. 아래 예제 코드를 보면 알 수 있다.
  • 직관적이고 사용이 간편:
    • 각 객체는 데이터베이스와의 연결을 직접 관리하므로, 코드 작성 시 CRUD 작업이 간단하고 직관적이다.
    • User 엔티티가 있다고 할 때, user.save()와 같이 간단하게 호출하면 그 객체를 데이터베이스에 저장할 수 있다.

예시 코드

import { Entity, PrimaryGeneratedColumn, Column, BaseEntity } from 'typeorm';

@Entity()
export class User extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column()
  email: string;

  // CRUD 작업 예시
  async saveUser() {
    await this.save();
  }

  async deleteUser() {
    await this.remove();
  }
}

// 사용 예시
async function createUser() {
  const user = new User();
  user.name = 'John Doe';
  user.email = 'john@example.com';
  await user.saveUser(); // User를 데이터베이스에 저장
}

// Entity 클래스만 정의했을 뿐인데 다음과 같은 구현이 가능하다.
const user = new User()
user.firstName = "Timber"
user.lastName = "Saw"
user.isActive = true
// 행 저장
await user.save()

// 행 삭제
await user.remove()

// Repository를 구현하지않아도 findBy같은 메서드를 사용할 수 있다.
const users = await User.find({ skip: 2, take: 5 })
const newUsers = await User.findBy({ isActive: true })
const timber = await User.findOneBy({ firstName: "Timber", lastName: "Saw" })

활성화 기록 패턴(Active Record Pattern)은 데이터베이스와 객체 간의 매핑을 수행하는 ORM(Object-Relational Mapping) 디자인 패턴 중 하나이다.

이 패턴은 객체데이터베이스와의 CRUD(Create, Read, Update, Delete) 작업을 직접 수행하도록 정의된다.

이는 객체 자체가 데이터베이스 관련 기능을 내포하고 있어, 데이터베이스와 상호작용하는데 필요한 코드가 그 객체의 메서드로 정의되는 방식이다.

 

BaseEntity

BaseEntity의 역할

BaseEntity는 TypeORM에서 활성화 기록 패턴을 구현할 수 있도록 지원하는 클래스이다.

이 클래스를 상속받는 엔티티는 데이터베이스와 상호작용할 수 있는 다음과 같은 메서드들을 자동으로 사용할 수 있게 된다:

  1. save():
    • 엔티티 인스턴스를 데이터베이스에 저장한다.
    • 이미 존재하는 레코드라면 업데이트하고, 새로운 레코드라면 추가한다.
    // save()
    const user = new User();
    user.name = 'John Doe';
    await user.save(); // 데이터베이스에 저장
    
  2. remove():
    • 엔티티 인스턴스를 데이터베이스에서 삭제한다.
    // remove()
    await user.remove(); // 데이터베이스에서 삭제
    
  3. find() / findOne():
    • 특정 조건에 따라 레코드를 조회한다.
    // **find() / findOne()**
    const users = await User.find(); // 모든 사용자 조회
    const specificUser = await User.findOne({ where: { name: 'John Doe' } }); // 특정 사용자 조회
    
  4. update():
    • 특정 레코드를 업데이트할 때 사용한다.

 

데이터 관리의 통합

  • 데이터의 CRUD 작업이 엔티티 클래스 내에서 모두 정의되어 있기 때문에, 데이터 로직데이터베이스 상호작용 로직이 통합된다.
  • 이러한 통합으로 인해 코드가 간결해지고 개발 속도가 빨라지는 장점이 있다.
  • 엔티티 인스턴스 자체에서 메서드를 호출해 데이터베이스 작업을 수행할 수 있기 때문에, 별도로 서비스나 레포지토리에서 데이터베이스 접근 로직을 구현할 필요가 없다.

 

추가로 공부해볼 개념

  • Data Mapper Pattern

 

참고자료

https://typeorm.io/active-record-data-mapper

https://en.wikipedia.org/wiki/Active_record_pattern

'Dev Framework > NestJS' 카테고리의 다른 글

[NestJS] enableCors( )  (1) 2024.11.21
[NestJS][TypeORM] Data Mapper Pattern  (0) 2024.11.19
[NestJS] pipe  (3) 2024.11.18
[NestJS] Provider란?  (0) 2024.10.27
개발자 성현