학습 키워드
- 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에서 활성화 기록 패턴을 구현할 수 있도록 지원하는 클래스이다.
이 클래스를 상속받는 엔티티는 데이터베이스와 상호작용할 수 있는 다음과 같은 메서드들을 자동으로 사용할 수 있게 된다:
- save():
- 엔티티 인스턴스를 데이터베이스에 저장한다.
- 이미 존재하는 레코드라면 업데이트하고, 새로운 레코드라면 추가한다.
// save() const user = new User(); user.name = 'John Doe'; await user.save(); // 데이터베이스에 저장
- remove():
- 엔티티 인스턴스를 데이터베이스에서 삭제한다.
// remove() await user.remove(); // 데이터베이스에서 삭제
- find() / findOne():
- 특정 조건에 따라 레코드를 조회한다.
// **find() / findOne()** const users = await User.find(); // 모든 사용자 조회 const specificUser = await User.findOne({ where: { name: 'John Doe' } }); // 특정 사용자 조회
- update():
- 특정 레코드를 업데이트할 때 사용한다.
데이터 관리의 통합
- 데이터의 CRUD 작업이 엔티티 클래스 내에서 모두 정의되어 있기 때문에, 데이터 로직과 데이터베이스 상호작용 로직이 통합된다.
- 이러한 통합으로 인해 코드가 간결해지고 개발 속도가 빨라지는 장점이 있다.
- 엔티티 인스턴스 자체에서 메서드를 호출해 데이터베이스 작업을 수행할 수 있기 때문에, 별도로 서비스나 레포지토리에서 데이터베이스 접근 로직을 구현할 필요가 없다.
추가로 공부해볼 개념
- Data Mapper 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 |