Active Record패턴과 Data Mapper 패턴

koreanhole·2021년 2월 2일
1

Active Record 패턴이란?

모든 query메소드들을 모델에 정의하고 객체의 저장, 제거 그리고 불러오는 기능들은 모델의 메소드를 통해 사용하는 패턴이다. 결과적으로 SQL을 직접 사용하지 않으면서 데이터를 조작할 수 있다.

Active Record 엔티티들은 Repository와 Entity Manager를 사용하지 않아도 된다. 모델 클래스를 정의하면서 BaseEntity클래스를 확장하였기 때문이다. BaseEntity클래스는 표준 Repository클래스의 대부분의 메소드를 갖고 있다.

Active Record 사용 예시

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

@Entity()
// 모든 active record엔티티들은 BaseEntity클래스를 확장해야한다.
export class User extends BaseEntity {

    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    firstName: string;

    @Column()
    lastName: string;

    @Column()
    isActive: boolean;

    static findByName(firstName: string, lastName: string) {
        return this.createQueryBuilder("user")
            .where("user.firstName = :firstName", { firstName })
            .andWhere("user.lastName = :lastName", { lastName })
            .getMany();
    }
}

위와같이 정의한 User모델을 사용하는것은 다음과 같다.

const timber = await User.findByName("Timber", "Saw");

Data Mapper 패턴이란?

Data Mapper 패턴에서는 모든 쿼리 메소드들을 별도의 클래스에 정의한다.
이때 생성된 별도의 클래스를 repository라고 부른다.
결국 데이터베이스를 접근하기 위해 모델이 아닌 repository를 통해 접근하는것을 Data mapper라고 한다.

Data Mapper 사용 예시

모델을 다음과 같이 정의한다.

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

@Entity()
export class User {

    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    firstName: string;

    @Column()
    lastName: string;

    @Column()
    isActive: boolean;

}

위에서 정의한 User모델에 대한 Repository를 다음과 같이 정의한다.

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

@EntityRepository()
export class UserRepository extends Repository<User> {

    findByName(firstName: string, lastName: string) {
        return this.createQueryBuilder("user")
            .where("user.firstName = :firstName", { firstName })
            .andWhere("user.lastName = :lastName", { lastName })
            .getMany();
    }

}

custom repository는 다음과 같이 사용한다.

const userRepository = connection.getCustomRepository(UserRepository);
const timber = await userRepository.findByName("Timber", "Saw");

참고자료

Active Record vs Data Mapper

0개의 댓글