Server/Node.js

Sequelize - 커스텀 메서드 (Custom method) 구현

JaeHoney 2022. 1. 8. 11:16

ORM 패턴?

ORM은 두 가지 패턴이 있습니다. Active Record (pattern)과 Data Mapper (Repository) pattern입니다.

 

Active Record pattern은 엔터티가 CRUD 기능을 하는 메서드들을 프로퍼티로 가지고 있어서 Model이 자기가 가지고 있는 메서드(쿼리)를 실행하는 형태입니다.

 

반면, Data Mapper pattern(with Repository)은 모델과 메서드(쿼리)를 분리합니다. Repository를 따로 두고, Repository에서만 메서드를 구현합니다.

 

Sequelize는 Active Record pattern입니다. 즉, 모델이 class method를 가지고 있어야 합니다. 그래서 우리는 User.findAll(), User.update() 등을 사용하게 되죠!

 

커스텀 메서드 구현 (Sequelize)

Sequelize v4 이전에는 model option에서 classMethods / instanceMethods에서 정의하기도 했고,

v6 이전에는 클래스 밖에서 Model.myCustomQuery = function (param, param2) {  }; 이렇게 정의하기도 했습니다.

 

하지만, Sequelize v6 부터는 모델 내부에서 static method / instance method를 선언하게 되어있습니다.

간단한 예시입니다!

class ResourceImage extends sequelize.Model {
    id: string;
    resourceId: string;
    imagePath: string;

    static updateAllByResourceId = async (resourceImages: ResourceImageDto[], resourceId: string, t?: Transaction): Promise<void> => {
        await ResourceImage.destroy({
            where: {
                resource_id: resourceId
            },
            transaction: t
        });
        Array.from(resourceImages).forEach((v) => { v.resourceId = resourceId });
        await ResourceImage.bulkCreate(resourceImages, {transaction: t});
    };
}

ResourceImage.init(
    {
        // 생략
    }
);

export {
    ResourceImage
};

이렇게 모델 내부에서 메서드(쿼리)를 가지고 있게 되고, Repository가 필요하지 않게 됩니다. Service Layer에서 Model을 이용해서 메서드를 호출하면 됩니다. ex. ResourceImage.updateAllByResourceId(resourceImageDto[], resourceId)

 

 

감사합니다.