• Sequelize.js 에서 Class 도입하기 :: 마이구미
    Nodejs 2018. 1. 1. 20:07
    반응형

    이 글은 Sequelize.js 을 다루지만, 튜토리얼은 아니다.

    중심 주제는 ES6의 class 키워드를 활용한 모델 정의에 대한 문법을 다루는 것이다.

    sequelize 의 기본적인 내용을 다루지만, 자세히 다루지 않는다.

    관련 코드 - https://github.com/hotehrud/sequelize-class

    참고 링크 - https://github.com/sequelize/sequelize/issues/6524


    본인이 이 글을 쓰게 된 동기는 다음과 같다.

    본인은 ES6의 class 키워드 도입 후부터 class 중심으로 코드를 짜고 있다.

    그래서 sequelize 관련 코드 또한 class 키워드를 사용하고 싶었다.


    먼저 간단히 sequlize 에 대해 살펴보자.


    Sequelize.js 는 무엇인가?


    Node.js 에서 가장 많이 사용하고 있는 ORM(Object-Relational mapping) 이다.

    ORM 은 용어 그대로 객체와 관계형 데이터베이스를 매핑하여 데이터베이스 또한 객체지향적으로 활용할 수 있다.

    데이터베이스와 객체 데이터 호환을 위해 나온 프로그래밍 기법이다.

    이로 인해, OOP 에 집중할 수 있을뿐만 아니라, 많은 이점을 얻을 수 있다.

    반대로 단점도 있지만, 사람마다 의견차이가 있다.


    sequelize 는 어떻게 사용하는가?


    기본적으로 sequelize 를 사용해서 쉽게 테이블 생성 및 질의를 할 수 있다.

    다음과 같이 쉽게 쿼리를 짤 필요없이 메소드를 사용할 수 있다.


    Table.findAll()

    => select * from Table


    일반적으로 테이블 생성은 define() 을 통해 사용한다.


    sequelize.define('modelName', { columnA: { type: Sequelize.BOOLEAN, validate: { is: ["[a-z]",'i'], // will only allow letters max: 23, // only allow values <= 23 isIn: { args: [['en', 'zh']], msg: "Must be English or Chinese" } }, field: 'column_a' // Other attributes here }, columnB: Sequelize.STRING, columnC: 'MY VERY OWN COLUMN TYPE' })


    위 코드와 같은 형태를 통해 원하는 구조를 가진 테이블을 만들 수 있다.

    위처럼 테이블의 정의에 대한 파일을 각각 분리한 후, fs 모듈을 통해 import 하는 것이 일반적이다.


    하지만, 이러한 모델에 대한 정의 파일은 sequelize.define() 에 의존한다.

    assoicate 기능과 같은 추가 및 확장이 어렵고, 효율적이지 못하다.


    문제점을 해결하기 위해 class 로 리팩토링을 한다고 가정하자.

    하지만 define() 사용은 외관상으로도 좋지 못할 뿐만 아니라, class 를 사용하는 이점도 없을 것이다.


    class 키워드 사용에 있어, Model 에 대한 정의 문법은 어떻게 작성해야하는가?


    sequelize 의 내부 소스를 들여다보면, 해결책을 찾을 수 있다.


    lib/sequelize.js

    define(modelName, attributes, options) { options = options || {}; options.modelName = modelName; options.sequelize = this; const model = class extends Model {}; model.init(attributes, options); return model; }


    define() 내부를 확인해보면, model.init() 이 생성 구문인 것을 확인할 수 있다.

    model 을 들여다보면, 데이터베이스의 테이블에 관련 클래스라는 것을 알 수 있다. (lib/model.js)

    결과적으로, Model 클래스를 확장해서 init() 을 활용할 수 있다.


    class Post extends Sequelize.Model { static init(sequelize) { return super.init({ title: { type: Sequelize.STRING, allowNull: false, }, textarea: { type: Sequelize.TEXT, allowNull: false, }, author: { type: Sequelize.STRING, allowNull: false }, }, { sequelize }) } static associate(models) { // hasMany, belongsTo, etc ... } }


    Model 클래스를 확장하고, super.init() 을 통해 관련 인스턴스를 생성한다.

    이와 같이 클래스를 통해 모델에 대한 정의 파일을 관리할 수 있다.

    또한 정의 파일 자체에서는 초기화 및 생성을 하지 않는 것을 선호한다면, 생성되지 않고 직접 호출해야하는 이점이 존재한다.

    결과적으로 오직 모델에 대한 정의 파일의 성격을 가지게 된다.


    자세한 이해를 위해서 Github 을 통한 전체 소스를 다운로드 후 사용해보길 바란다.

    제공되는 예제는 DB 설정만 한다면, 바로 이용할 수 있다.

    반응형

    댓글

Designed by Tistory.