시퀄라이즈(Sequelize)(2) 모델, 관계 정의

임쿠쿠·2020년 9월 29일
2

Sequelize

목록 보기
2/3
post-thumbnail

시퀄라이즈(Sequelize) 모델 정의

MySQL의 테이블은 시퀄라이즈의 모델과 대응됩니다. 시퀄라이즈는 모델과 MySQL의 테이블을 연결해주는 역할을 합니다.

앞서 만든 models 폴더에서 user.js 파일을 만든 후 다음과 같이 작성합니다.

//models/user.js
const Sequelize = require('sequelize');

module.exports = class User extends Sequelize.Model {
  static init(sequelize) {
    return super.init({
      name: {
        type: Sequelize.STRING(20),
        allowNull: false,
        unique: true,
      },
      age: {
        type: Sequelize.INTEGER.UNSIGNED,
        allowNull: false,
      },
      married: {
        type: Sequelize.BOOLEAN,
        allowNull: false,
      },
      comment: {
        type: Sequelize.TEXT,
        allowNull: true,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
        defaultValue: Sequelize.NOW,
      },
    }, {
      sequelize,
      timestamps: false,
      underscored: false,
      modelName: 'User',
      tableName: 'users',
      paranoid: false,
      charset: 'utf8',
      collate: 'utf8_general_ci',
    });
  }
};

먼저 User 모델을 만들고 모듈로 exports 했습니다. User 모델은 Sequelize.Model을 확장한 클래스로 선언합니다. 모델은 크게 static init 메서드와 static associate 메서드로 나뉩니다.

init 메서드에는 테이블에 대한 설정을 하고 associate 메서드에는 다른 모델과의 관계를 적습니다. init 메서드부터 살펴보겠습니다. super.init 메서드의 첫 번째 인수가 테이블 컬럼에 대한 설정이고, 두 번째 인수가 테이블 자체에 대한 설정입니다.(왜 id값이 없는지 의아해 하실 수 있는데 sequelize는 알아서 id를 기본 키로 연결하므로 id 칼럼은 적어줄 필요가 없습니다.)

MySQL과 시퀄라이즈 자료형 비교
super.init 첫번째 인수 내의 칼럼명 type이 기존 MySQL과 다른데 간단히 비교해 보겠습니다.

MySQL시퀄라이즈
VARCHAR(100)STRING(100)
INTINTEGER
TINYINTBOOLEAN
DATETIMEDATE
INT UNSIGNEDINTEGER.UNSIGNED
NOT NULLallowNull: false
UNIQUEunique: true
DEFAULT now()defaultValue: Sequelize.NOW

super.init 메서드의 두 번째 인수는 테이블 옵션입니다.

  • sequelize : static init 메서드의 매개변수와 연결되는 옵션입니다.
  • timestamps : 현재 false로 되어 있는데, 이 속성 값이 true면 시퀄라이즈는 createdAt과 updatedAt 컬럼을 추가합니다. 각각 로우가 생성될 떄와 수정될 떄의 시간이 자동으로 입력 됩니다.
  • underscored : 시퀄라이즈는 기본적으로 테이블명과 컬럼명을 캐멀 케이스로 만듭니다. 이를 스네이크 케이스로 바꾸는 옵션입니다.
  • modelName : 모델 이름을 설정할 수 있습니다.
  • tableName : 실제 데이터베이스의 테이블 이름이 됩니다. 기본적으로 모델 이름을 소문자 및 복수형으로 만듭니다.
  • paranoid : true로 설정 시 deletedAt 칼럼이 생깁니다. 로우를 삭제할 때 완전히 지워지지 않고 지운 시각이 기록됩니다. 이렇게 하는 이유는 나중에 로우를 복원하기 위해서 입니다. 로우를 복원해야 하는 상황이 생길 시 미리 true로 설정합니다.
  • charset과 collate : 각각 utf8과 utf8_general_ci로 설정해야 한글이 입력됩니다.

시퀄라이즈(Sequelize) 관계 정의

위에서 작성한 users 테이블과 타 테이블 간의 관계를 정의해보겠습니다. 예를 들어 사용자 한 명은 댓글을 여러 개 작성할 수 있습니다. 하지만 댓글 하나에 사용자가 여러 명일 수는 없습니다. 이러한 관계를 일대다(1:N) 관계라고 합니다.

다른관계로 일대일, 다대다 관계가 있습니다. 예를 들어 사용자와 사용자에 대한 정보 테이블은 1:1 관계입니다. 다대다 관계는 게시글 테이블과 해시태그 테이블 관계를 예로 들 수 있습니다. 한 게시글에는 해시태그가 여러 개 달릴 수 있고, 한 해시태그도 여러 게시글에 달릴 수 있습니다.

1:N 관계

static associate(db) {
    db.User.hasMany(db.Comment, { foreignKey: 'commenter', sourceKey: 'id' });
  }
---------------------------------------------------------------------------------
static associate(db) {
    db.Comment.belongsTo(db.User, { foreignKey: 'commenter', targetKey: 'id' });
  }

시퀄라이즈에서 1:N 관계를 hasMany라는 메서드로 표현합니다. 즉 USER 테이블의 로우하나를 불러올 때 연결된 Comment 테이블의 로우들도 같이 불러올 수 있습니다. 반대로 belongsTo 메서드도 있습니다. Comment 테이블의 로우를 불러올 때 연결된 USER 테이블의 로우를 가져옵니다.

정리하면 다른 모델의 정보가 들어가는 테이블에 belongsTo를 사용합니다. 시퀄라이즈는 모델 간 관계를 파악하기 위해 각각 foreignKey를 설정하고 hasMany 메서드에서는 sourceKey를 belongsTo 메서드에는 targetKey를 넣습니다.

profile
Pay it forward

0개의 댓글