wam
w__am 개발노트
wam
  • 분류 전체보기 (165)
    • CS 지식 (10)
      • 자료구조 (0)
      • 알고리즘 (0)
      • 컴퓨터 구조 (0)
      • 운영체제 (0)
      • 네트워크 (7)
      • 데이터베이스 (0)
      • 디자인 패턴 (3)
    • Frontend (131)
      • Three.js (64)
      • NPM (1)
      • Nest.js (19)
      • React (10)
      • Apollo (7)
      • TypeScript (2)
      • JavaScript (12)
      • HTML, CSS (1)
      • Jest (3)
      • E2E (5)
      • Cypress (7)
    • Database (12)
      • TypeORM (12)
    • IT 지식 (8)
      • 클라우드 서비스 (3)
      • 네트워크 (1)
      • 데이터 포맷 (2)
      • 기타 (2)
    • IT Book (2)
    • 유용한 사이트 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 🐱 Github

인기 글

태그

  • 렌더링 성능 최적화
  • getelapsedtime()
  • gridhelper
  • reactive variables
  • 함수 리터럴
  • 함수 표현식
  • isabstract
  • 데이터 포맷
  • getdelta()
  • Interface
  • mapped types
  • 함수 선언문
  • API
  • 초기 환경설정
  • math.cos()
  • joi 에러
  • threejs 개발 할 때 도움을 줄 수 있는 유틸리티
  • Decorators
  • axeshelper
  • three.js 구성 요소
  • 삼각함수
  • type-graphql
  • e.preventdefault()
  • 오프-프레미스(off-premise) 방식
  • 스코프
  • math.sin()
  • 디자인 패턴
  • react 성능 최적화
  • 함수의 범위
  • 원형적인 움직임

최근 글

관리자

글쓰기 / 스킨편집 / 관리자페이지
hELLO · Designed By 정상우.
wam

w__am 개발노트

TypeORM의 데이터 접근 패턴 - Data Mapper, Active Record
Database/TypeORM

TypeORM의 데이터 접근 패턴 - Data Mapper, Active Record

2024. 7. 29. 23:28

 

Data Mapper

데이터 매퍼(Data Mapper) 패턴은 데이터베이스와 애플리케이션 객체 사이의 매핑을 분리하여, 데이터베이스 작업을 전담하는 별도의 레포지토리(Repository)나 매퍼 클래스를 사용한다. 이 패턴에서는 엔티티 클래스는 데이터베이스 작업을 직접 수행하지 않고, 매퍼가 데이터베이스와의 상호작용을 담당한다.

 

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

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

  @Column()
  name: string;

  @Column()
  age: number;
}

// Repository를 사용하여 데이터베이스 작업 수행
import { EntityRepository, Repository } from 'typeorm';

@EntityRepository(User)
export class UserRepository extends Repository<User> {
  // 추가적인 데이터베이스 작업 메서드를 정의할 수 있습니다.
}
// 추가적인 데이터베이스 작업 메서드를 정의할 수 있습니다.

import { EntityRepository, Repository } from 'typeorm';
import { User } from './user.entity';

@EntityRepository(User)
export class UserRepository extends Repository<User> {
  // 사용자 이름으로 사용자 찾기
  async findByName(name: string): Promise<User[]> {
    return this.createQueryBuilder('user')
      .where('user.name = :name', { name })
      .getMany();
  }

  // 특정 나이 이상인 사용자 찾기
  async findByMinAge(age: number): Promise<User[]> {
    return this.createQueryBuilder('user')
      .where('user.age >= :age', { age })
      .getMany();
  }

  // 사용자 나이 업데이트
  async updateUserAge(userId: number, newAge: number): Promise<void> {
    await this.createQueryBuilder()
      .update(User)
      .set({ age: newAge })
      .where('id = :id', { id: userId })
      .execute();
  }

  // 사용자 삭제 (Soft Delete 사용)
  async softDeleteUser(userId: number): Promise<void> {
    await this.updateUserAge(userId, null); // age를 null로 설정하거나 다른 Soft Delete 전략을 사용할 수 있습니다.
  }
}
  • Repository라는 별도의 클래스에서 모든 쿼리 방법을 정의하고, 리포지토리를 사용하여 개체를 저장, 제거 및 로드할 수 있다.
  • Data Mapper에서 entity는 매우 멍청하다. 속성을 정의할 뿐이고 일부 "더미 같은" 방법을 가지고 있을 수 있다.
  • 모델 대신 저장소 내에서 데이터베이스에 액세스 할 수 있는 접근 방식이다

 

 

Active Record

액티브 레코드(Active Record) 패턴은 엔티티 클래스가 데이터베이스 작업을 직접 수행하는 방식이다. 엔티티 클래스는 데이터베이스의 레코드와 직접적으로 연관되며, CRUD 작업을 직접 수행할 수 있는 메서드를 포함한다.

 

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

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

  @Column()
  name: string;

  @Column()
  age: number;

  // CRUD 작업 메서드 (예: find, save, remove) BaseEntity에서 제공됨
}

// 데이터베이스 작업 수행
const user = new User();
user.name = 'John Doe';
user.age = 30;
await user.save(); // 데이터베이스에 저장
// CRUD 작업 메서드 (예: find, save, remove) BaseEntity에서 제공됨


// 사용자 생성
const newUser = User.create({
  name: 'John Doe',
  age: 30
});
await newUser.save(); // save 메서드를 사용하여 데이터베이스에 저장

// 사용자 조회
const user = await User.findOne({ where: { name: 'John Doe' } }); // findOne 메서드를 사용하여 특정 조건의 사용자 조회

// 사용자 목록 조회
const users = await User.find(); // find 메서드를 사용하여 모든 사용자 목록 조회

// 사용자 업데이트
await User.update({ name: 'John Doe' }, { age: 31 }); // update 메서드를 사용하여 특정 조건의 사용자 정보 수정

// 사용자 삭제
await User.delete({ name: 'John Doe' }); // delete 메서드를 사용하여 특정 조건의 사용자 삭제

// 소프트 삭제 (삭제 플래그를 사용)
await User.softRemove({ id: 1 }); // softRemove 메서드를 사용하여 사용자 소프트 삭제
  • Ruby on Rails, Django는 Active Record를 사용한다.
  • 모델 자체 내에서 모든 쿼리 방법을 정의하고 모델 방법을 사용하여 개체를 저장, 제거 및 로드할 수 있다.
  • 모델 내에서 데이터베이스에 액세스할 수 있는 접근 방식이다.

 

 

어떤 것을 선택해야 할까?

 

Active Record

단순함을 유지하는데 도움,소규모 앱에서 유용

  • 데이터 접근 로직과 비즈니스 로직이 결합된 상태.
  • 간단하고 직관적이다.

 

 

Data Mapper

유지 보수성에 도움이 됨, 대규모 앱에서 유용

  • 데이터 접근 로직과 비즈니스 로직이 분리된 형태.
  • 유연하고, 복잡한 도메인 로직을 가진 대규모 어플리케이션에 적합

 

 

NestJS에서는 Data Mapper 패턴을 사용하는 장점

  • TypeORM 개발 환경에서 Repository를 사용하는 모듈을 쓸 수 있기 때문
  • Repository를 사용하면 어디서든지 접근 가능하다.
  • 구현하는 서비스에서 접근이 가능하고 테스팅할 때도 접근이 가능하다.
  • NestJS의 경우에는 자동으로 Repository를 사용할 수 있도록 클래스에 자동으로 준비해 준다.

 

 

 

저작자표시 변경금지 (새창열림)

'Database > TypeORM' 카테고리의 다른 글

EntityRepository - deprecated 되었다.  (0) 2024.08.02
TypeORM의 Entity  (0) 2024.07.29
TypeORM에서 제공하는 특별한 데코레이터 , 엔티티의 생성 및 수정 일자를 자동으로 관리  (0) 2024.07.29
TypeORM의 Listener  (0) 2024.07.29
TypeORM 이란  (0) 2024.07.29
    'Database/TypeORM' 카테고리의 다른 글
    • TypeORM의 Entity
    • TypeORM에서 제공하는 특별한 데코레이터 , 엔티티의 생성 및 수정 일자를 자동으로 관리
    • TypeORM의 Listener
    • TypeORM 이란
    wam
    wam

    티스토리툴바