Sungtt

[Sequelize] 2 - DB연결하기 본문

Node

[Sequelize] 2 - DB연결하기

sungtt 2022. 3. 2. 17:49

[Sequelize] 2 - DB연결하기

1편에서 준비물을 전부 설치했다면 이어서 모델을 생성하고 DB를 연결해보자.

앞서 말한 준비물은 sequelize, sequelize-cli, mysql2다.

 

 

1 - 프로젝트 생성

작업할 디렉토리에 들어가서, 명령어를 통해 sequelize 프로젝트를 생성하자.

# npm
npx sequelize-cli init
# yarn
yarn sequelize-cli init

프로젝트 생성 시 초기 구조

2 - config.json 설정

./config 디렉토리에 들어있는 config.json은 연결할 DB의 정보를 설정해놓는다.

나는 mysql 로컬환경에서, test라는 스키마에서 작업 할 것이기때문에 코드를 아래와 같이 작성했다.

{
  "development": {
    "username": "root",
    "password": "password",
    "database": "test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}

 

3 - index.js 설정

models 디렉토리의 index.js에 들어가 아래 코드로 변경한다.

기존에 써있는 코드는 오류가 난다고들 한다. 왜인지는 왜 안알려주는걸까?

우선 사용법을 터득하고 원인을 후술하겠다.

// index.js
const path = require('path');
const Sequelize = require('sequelize');

const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};

const sequelize = new Sequelize(config.database, config.username, config.password, config);

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

4 - server.js에 연결하기

이제 models의 상위경로에 server.js를 만들고, 우리가 설정한 sequelize를 연결해주자.

sync 메서드를 통해서 mysql과 연결된다.

// server.js
const express = require('express');
const app = express();
const sequelize = require('./models').sequelize;

sequelize
    .sync({force: false})
    .then(() => {
        console.log('데이터베이스 연결됨.');
    })
    .catch((err) => {
        console.error(err);
    });

app.listen(8000, () => {
    console.log(' 8000번 포트에서 대기 중');
});

 그 다음 server.js를 node로 실행시켜 콘솔에 "데이터베이스 연결됨" 출력된다면 정상적으로 연결된 것이다.

 

5 - model과 스키마 만들어 주기

model은 mysql의 스키마와 대응하는 개념이다.

model에서 설정한대로 mysql에 스키마가 생성되는것이다.

models 디렉토리에 User.js 파일을 만들어주고 아래 코드를 넣자

const Sequelize = require('sequelize');

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: 'utf8mb4',
            collate: 'utf8mb4_general_ci'
        });
    }
    static associate(db) {}
};

module.exports = User;

모델은 Sequelize.Model을 확장한 클래스로 선언한다. 그리고 두가지 메서드를 가지고 있는데,

 static init 메서드와 static asscociate 메서드이다. init은 테이블 설정, associate는 다른 모델과의 관계를 적는다.

initsuper.init 메서드 첫 번째 인수는 테이블 컬럼에 대한 설정이고, 두 번째 인수는 테이블 자체에 대한 설정이다.

 

sequelize는 id를 기본키로 알아서 맵핑해주기때문에, 따로 작성할 필요가 없다.

다만 나머지 자료형들은 mysql과 다르기때문에 대응하는 자료형을 확인하고 작성해야한다.

 

테이블 설정의 옵션들을 살펴보자면

  • sequelize: static init 메서드의 매개변수와 연결되는 옵션으로, db.sequelize 객체를 넣어야 한다. 나중에 model/index.js에서 연결한다.
  • timestamps: 현재 false로 설정되어 있다. 이 속성 값이 true면 시퀄라이즈는 createdAt과 updatedAt 컬럼을 추가하며, 각각 로우가 생성될 때와 수정될 때의 시간이 자동으로 입력된다. 그러나 예제에선 직접 created_at 컬럼을 만들었으므로 timestamps 속성이 필요없다.
  • underscored:  시퀄라이즈는 기본적으로 테이블명과 컬럼명을 카멜 표기법 (camel case) 으로 만든다. 이를 스네이크 표기법 (snake case) 으로 바꾸는 옵션이다 (예를들어 updatedAt 을 updated_at 으로).
  • modelName: 모델 이름을 설정할 수 있다. 노드 프로젝트에서 사용한다.
  • tableName: 실제 데이터베이스의 테이블 이름. 기본적으로 모델 이름의 소문자 및 복수형으로 만든다. 예를 들어 모델 이름이 User 라면 테이블 이름은 users 이다.
  • paranoid: true로 설정하면 deletedAt이라는 컬럼이 생긴다. 로우를 삭제할 때 완전히 지우지 않고, deletedAt에 지운 시각이 기록된다. 로우를 조회하는 명령을 내렸을 경우 deletedAt의 값이 null인 로우를 조회한다. 이렇게 하는 이유는 후에 로우를 복원하기 위해서다. 로우를 복원해야 할 상황이 생길 것 같다면 미리 true로 설정해두자.
  • charset, collate: 각각 utf8 과 utf8_general_ci 로 설정해야 한글이 입력된다. 이모티콘까지 입력할 수 있게 하고 싶다면 utf8mb4 와 utf8mb4_general_ci 를 입력한다.

 

이어서 user.js를 index.js에 연결시켜주자.

// index.js
const path = require('path');
const User = require('./user');
const Sequelize = require('sequelize');


const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};

const sequelize = new Sequelize(config.database, config.username, config.password, config);

db.sequelize = sequelize;
db.Sequelize = Sequelize;

db.User = User;
User.init(sequelize);
User.associate(db);

module.exports = db;

 db라는 객체에 User를 담았다. 앞으로 db객체를 require하여 User 모델에 접근할 수 있다.

User.init은 User모델의 init메서드를 호출한다. init이 호출되어야 테이블이 모델로 연결된다.

User.associate도 다른 테이블과의 관계를 연결하기때문에 실행해준다.

그리고 server.js를 재부팅시켜주면 테이블이 생성되는걸 확인할 수 있다.

mysql의 쿼리문이 보일것이다. 
workbench에서 확인한 생성된 테이블

 

6 - 로우 생성 쿼리

생성한 테이블에 로우를 추가해보자.

sequelize 쿼리를 이용하면 mysql 쿼리처럼 사용할 수 있다.

const path = require('path');

,,,
// 로우를 생성하는 create 쿼리
User.create({
  name: 'sungtt',
  age: 27,
  married: false,
  comment: '안녕하세요.'
});
,,,

module.exports = db;

 

다시 server를 실행시켜보면 테이블에 로우가 추가되었다.

 

 

다음엔 CRUD를 전체적으로 훑고, 실질적으로 이용할 수 있는 방법을 알아보자.

 

Comments