Server/NodeJS

[NodeJS] Sequelize : ORM(Object-relational Mapping) 사용하기

백엔드 규니 2020. 10. 18. 03:17
728x90
반응형

노드에서 MySQL 작업을 쉽게 할 수 있도록 도와주는 라이브러리가 있다.(이번 글에서는 MySQL을 사용할 것이다) 바로 시퀄라이즈(Sequelize)이다. 시퀄라이즈는 ORM(Object-relational-Mapping)이다. ORM은 자바스크립트 객체와 데이터베이스의 릴레이션을 매핑해주는 도구이다.

 

시퀄라이즈를 쓰는 이유는 자바스크립트 구문을 알아서 SQL로 바꿔주기 때문이다. 따라서 SQL 언어를 직접 사용하지 않아도 자바스크립트만으로 MySQL을 사용할 수 있다. (하지만 SQL을 모르는 채로 Sequelize를 사용하는 것은 매우 비추이다)

  

 

1. Express 프로젝트 생성하기

Express 프로젝트이름
ex) Express NodeJS_ORM

 

그러면 위와 같이 Express 프로젝트 구조가 생겼을 것이다. 그리고 터미널에서 아래의 명령어를 입력하여 설치해보자.  

npm install
npm install mysql2 
npm install sequelize
npm install sequelize-cli (Mac에서 권한거부가 난다면 앞에 sudo를 붙혀서 설치) 
sequelize init 

 

마지막 명령어를 쳤을 때 config, models, migrations, seeders 폴더가 생긴 것을 확인할 수 있다. models 폴더 안의 index.js가 생성되었는지 확인해보자. 이 파일이 Sequelize에서 가장 중요한 파일이라고 생각하면 된다. 

 

원래 index.js에 있는 코드를 모두 지우고 아래의 코드로 대체해보자. 

 

index.js

const Sequelize = require('sequelize');

const env = process.env.NODE_ENV || 'development';         // 개발용 환경 설정
const config = require('../config/config.json')[env];      // Sequelize 설정 파일
const db = {};

// Sequelize 인스턴스화
const sequelize = new Sequelize(config.database, config.username, config.password, config);  

db.Sequelize = Sequelize;  // db객체에 Sequelize 패키지 넣기
db.sequelize = sequelize;  // db객체에 Sequelize 인스턴스 넣기

module.exports = db;  // 모듈화

config.json

{
  "development": {        // development를 사용할 것임
    "username": "root",   // DB 접속 아이디
    "password": "root",   // DB 접속 비번
    "database": "nodeJS", // DB 스키마 이름 설정 
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "test": {
    "username": "root",
    "password": null,
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "production": {
    "username": "root",
    "password": null,
    "database": "database_production",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}

위와 같이 수정을 한 후에 터미널에서 아래와 같이 입력을 하면 Sequelize에서 스키마를 생성해준다. 

 

 

그리고 MySQLWorkbench에서 스키마가 잘 생성되었는지 확인을 해보자.

 

위와 같이 nodeJS가 잘 생성이 된 것을 확인할 수 있다. 

 

 

테이블 만들기

이제 User테이블, Comment 테이블을 만들어보려 한다. models 패키지 아래에 comment.js, user.js를 만들어보자.

 

그리고 index.js 파일에 모듈화 시키는(module.exports = db) 위에 아래 두 줄의 코드를 추가하자.

db.User = require('./user')(sequelize, Sequelize);
db.Comment = require('./comment')(sequelize, Sequelize);

 

그리고 이제 models 패키지 아래에 만들었던 comment.js와 user.js를 하나씩 완성해보자.

 

user.js

/**
 * User 테이블 만들기  
 * @param {Sequelize} 
 * @param {DataTypes}  
 * 이름, 나이, 결혼여부, 자기소개, 생성일
 */

module.exports = (Sequelize, DataTypes) => {
  return Sequelize.define('user', {
    name: {
      type: DataTypes.STRING(20),    // type : 자료형
      allowNull: false,              // allowNull: NULL이어도 되니?
      unique: true,                  // 고유값 여부 
    },
    age: {
      type: DataTypes.INTEGER.UNSIGNED,
      allowNull: false,
    },
    married: {
      type: DataTypes.BOOLEAN,
      allowNull: false,
    },
    comment: {
      type: DataTypes.TEXT,
      allowNull: true
    },
    create_at: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: Sequelize.literal('now()') // 회원이 생길 때 자동으로 날짜가 등록이 됨
    },
  }, {
    timestamps: false,  // 생성일을 Sequelize가 자동으로 생성하지 말라는 옵션 
    underscored: true,   // Snake Case를 권장한다는 옵션
  })
}

  • type : 자료형
  • allowNull: NULL이 가능한지 여부
  • comment: 컬럼설명
  • primaryKey: 기본키 여부
  • timestamps: 생성일을 Sequelize가 자동으로 생성할지 말지를 정하는 옵션
  • underscored: Snake Case 코딩 스타일을 원하는 옵션

 

comment.js

/**
 * Comment 테이블 만들기  
 * @param {Sequelize} 
 * @param {DataTypes} 
 * 작성자, 댓글 내용, 생성일
 */ 

module.exports = (Sequelize, DataTypes) => {
  return Sequelize.define('comment', {
    comment: {
      type: DataTypes.STRING(100),
      allowNull: false
    },
    created_at: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: Sequelize.literal('now()')
    },
  }, {
    timestamps: false,  // 생성일을 Sequelize가 자동으로 생성하지 말라는 옵션 
    underscored: true,   // Snake Case를 권장한다는 옵션
  });
}

나머지는 위와 같은데 한 가지 다른 점이 있다. 이번에는 commenter를 적어주지 않는다. 

 

 

commenter를 적지 않는 이유가 무엇일까?

commenter는 댓글을 적은 사람이다. 즉, User 중에 한명이라는 뜻이다. User - Comment의 관계는 일대다이다. 유저 한명이 여러개의 댓글을 작성할 수 있기 때문이다. (MySQL과 같은 관계형 DB는 테이블간의 관계가 중요하다)

 

index.js 파일에 테이블 만들었을 때 적었던 코드 아래에 두 줄을 추가해주자.

db.User.hasMany(db.Comment, { foreignKey: 'commenter', sourceKey: 'id'});   // 사용자는 여러개의 댓글을 가질 수 있음
db.Comment.belongsTo(db.User, { foreignKey: 'commenter', targetKey: 'id' }); // 작성자가 한명임  

위와 같이 작성을 해주면 user.js에는 id 컬럼이 존재하지 않지만 PK처럼 유저가 추가될 때마다 id에 1, 2, 3 . . . 값이 들어간다. 그리고 User테이블에 id 값을 참조하는 Comment 테이블은 외래키인 id값을 갖게 되는 것이다. 

 

  • 1대1 : hasOne, belongsTo
  • 1대다: hasMany, belongsTo
  • 다대다: belongsToMany

 

 

그리고 이제 중앙통제실 app.js와 연결시키자

app.js에 위와 같이 2줄의 코드를 추가해주자. 그리고 npm start를 해주면 아래와 같이 Sequelize에서 SQL 쿼리를 이용해서 테이블을 만들어준다.

 

그리고 MySQLWorkbench에서 테이블이 만들어졌는지 확인을 해보면 아래와 같이 잘 생성이 된 것을 확인할 수 있다.

 

 

이렇게 간단하게 Sequelize를 사용하여 테이블을 만들고 테이블간의 관계를 설정하는 예제를 해보았다. 

반응형