Node.js 시퀄라이즈로 MySQL 연동하기

버건디·2022년 12월 12일
0

Node.js

목록 보기
10/15
post-thumbnail

🔍 시퀄라이즈(Sequelize)란 ?

시퀄라이즈란 ORM 으로 분류된다.

ORM이란 자바스크립트의 객체와 데이터베이스를 연결해주는 도구라고 생각하면 된다.

관계형 데이터베이스, SQL에서는 테이블을 사용하는데, 자바스크립트에서 데이터는 객체를 사용하므로, 둘 간의 불일치가 존재한다.

ORM 을 통해서 객체 간의 관계를 바탕으로 SQL을 자동으로 생성해서 불일치를 해결해주는 도구이다.


🔍 시퀄라이즈 설치

npm install sequelize sequelize-cli mysql2

sequelize-cli 는 시퀄라이즈 명령어를 실행하기 위한 패키지이고, mysql2는 MySQL과 시퀄라이즈를 이어주는 드라이버이다.

npx sequelize init

전역 설치를 피하기 위해 npx로 위의 명령어를 입력하면 config, models, migrations, seeders 폴더가 생성된다.

🔍 config

생성된 config 폴더에 가보면 config.json 파일이 있는데, DB 연결 정보를 저장하는 파일이다.

🔍 migrations

git과 비슷하게, 데이터베이스 변화하는 과정들을 추적해나가는 정보로, 실제 데이터베이스에 반영할 수도 있고 변화를 취소할 수도 있다.

🔍 models

데이터베이스 각 테이블의 정보 및 필드타입을 정의하고 하나의 객체로 모은다.
워크벤치에서 테이블을 정의했듯이 여기서도 모델을 만들어 주는 것이다.
❗️ 각각의 테이블들은 MySQL 내에서 미리 만들어져있어야 한다 ❗️

🔍 seeders

서버가 시작될때 가지고 있어야할 정적 데이터들을 DB에 추가시켜준다.


sequelize-cli 가 자동으로 설치해주는 models/index.js 폴더에 있는 코드는 그대로 사용할 때 에러가 발생하고, 필요없는 부분이 많으므로

const Sequelize = require('sequelize');

const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env]; //config.json 불러오기
const db = {}; // 실제 데이터베이스가 이 db 객체와 연결됨

const sequelize = new Sequelize(config.database, config.username, config.password, config); 
// 데이터베이스와 연결하기, 시퀄라이즈 ORM 객체 생성

db.sequelize = sequelize; // 나중에 연결 객체 재사용을 위해 넣어둠, db객체에 sequelize라는 프로퍼티 추가

module.exports = db; // export 하기

이렇게 변경해준다.

config.json 에서 데이터베이스 설정을 불러온 후에, new Sequelize 를 통해서 데이터베이스와 연결했다.

나중에 재사용을 위해서 db라는 빈 객체에 넣어두었다.


🔍 워크벤치에서 테이블 설정


🔍 익스프레스와 MySQL 연결하기

1. config.json 에서 셋팅해주기

{
  "development": {
    "username": "root",
    "password": "비밀번호",
    "database": "database_development",
    "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"
  }
}

config.json 파일의 코드에서, password와 database 부분이 있는데 password는 현재 MySQL root 비밀번호를 입력하고 database는 MySQL 에서 연결할 데이터베이스명을 입력하면 된다.

test와 production은 테스트와 배포환경에서 접속하기 위해 사용되는 것이므로 지금은 설정하지 않아도 된다.

server.js 에서 시퀄라이즈와 익스프레스 연동

const express = require('express');
const app = express();
const path = require('path');
const morgan = require('morgan');
const {sequelize} = require('./models'); // db.sequelize 객체

app.set('port', process.env.PORT||3001);

sequelize.sync({force : false}) // 서버 실행시 MySQL 과 연동되도록 하는 sync 메서드 
// force : true 로 해놓으면 서버 재시작마다 테이블이 재생성됨. 테이블을 잘못 만든 경우에 true 로 설정
.then(() => {
    console.log('데이터 베이스 연결 성공');
})
.catch((err) => {
    console.log(err);
});

app.use(morgan('dev'));
app.use(express.static(path.join(__dirname, "index.html")));
app.use(express.json());
app.use(express.urlencoded({extended : false}));

app.use((req, res, next) =>{
    const error = new Error(`${req.method} ${req.url} 라우터가 없습니다.`);
    error.status = 404;
    next(error);
});

app.use((err,req ,res, next) => {
    res.locals.message = err.message;
    res.locals.error = process.env.NODE_ENV !== 'production' ? err : {};
    res.status(err.status || 500);
    res.render('error');
});

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

잘 연결된 걸 확인할 수 있다.


🔍 모델 정의하기

user.js

const Sequelize = require('sequelize');

module.exports = class User extends Sequelize.Model{
    static init(sequelize){ // init 메서드에는 테이블에 대한 설정
        return super.init({ // super.init메서드의 첫번째 인수가 테이블 컬럼에 대한 설정
            name : {
                type : Sequelize.STRING(20),
                allowNull : false, // NOTNULL
                unique : false, // UNIQUE 
            },
            age : {
                type : Sequelize.INTEGER.UNSIGNED, // INTEGER.UNSIGNED
                allowNull : false
            },
            married : {
                type : Sequelize.BOOLEAN, // TINYINT
                allowNull : null,
            },
            comment : {
                type : Sequelize.TEXT,
                allowNull : true,
            },
            created_at : {
                type : Sequelize.DATE,
                allowNull : false,
                defaultValue : Sequelize.NOW, //DEFAULT now()
            },
        },
        { // super.init 메서드의 두번째 인수가 테이블 자체에 대한 옵션
            sequelize, // static init 메서드의 매개변수와 연결되는 옵션 db.sequelize 객체를 넣어야함
            timestamps : false, // 속성값이 true 라면 시퀄라이즈는 createdAt 과 updatedAt 컬럼을 추가해야함. 
          //각각 로우가 생성될때와 수정될때의 시간이 자동으로 입력됨. 자동으로 날짜 컬럼이 추가되는 기능
            underscored : false, // 시퀄라이즈는 기본적으로 테이블명과 컬럼명을 카멜케이스로 적음(created_at 을 createdAt 으로 표기)
            // 이를 스네이크 케이스 (createdAt을 created_at 으로 표기)로 바꿔줌
            modelName : "User", // 모델 이름을 설정할 수 있음.
            tableName : "users", // 실제 데이터베이스의 테이블 이름이 됨.
          //기본적으로 모델이름의 소문자 및 복수형으로 해야함.
            paranoid : false, //true 로 설정시 deletedAt 이라는 컬럼이 생김. 
          // 로우를 삭제할때 완전히 지워지지 않고 deletedAt 에 지운 시각이 기록됨. 
          // 나중에 로우를 복원해야할 상황이 있다면 true 로 설정
            charset : "utf8", // 한글을 입력받기 위한 설정
            collate : 'utf8_general_ci', // 한글을 입력받기 위한 설정
        });
    }
    static associate(db){} //static associate 메서드에는 다른 모델과의 관계 다른 모델들과 연결할때 사용
}

comment.js

const Sequelize = require('sequelize');

module.exports = class Comment extends Sequelize.Model{
    static init(sequelize){
        return super.init({
            comment : {
                type : Sequelize.STRING(100),
                allowNull : false,
            },
            created_at:{
                type : Sequelize.DATE,
                allowNull : true,
                defaultValue : Sequelize.NOW,
            },
        },{
            sequelize,
            timestamps : false,
            modelName : 'Comment',
            tableName : "comments",
            paranoid : false,
            charset : 'utf8mb4', // 이모티콘까지 입력받을수 있도록
            collate : 'utf8mb4_general_ci', // 이모티콘까지 입력받을수 있도록
        });
    }
    static associate(db){}
}

🔍 models/index.js 랑 연동하기

const Sequelize = require('sequelize');
const User = require('./table/user');
const Comment = require('./table/comment');
const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];
const db = {};

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

db.sequelize = sequelize;

db.User = User; // db 객체에 user 모델 담기
db.Comment = Comment; // db 객체에 comment 모델 담기

User.init(sequelize); // user모델에서 init 메서드(테이블설정하는 메서드)불러오기 
//init이 실행되어야 테이블이 모델로 연결됨
Comment.init(sequelize); // comment 모델에서 init 메서드(테이블 설정하는 메서드) 불러오기 
//init이 실행되어야 테이블이 모델로 연결됨

User.associate(db); // 다른 테이블과의 관계를 연결함
Comment.associate(db); // 다른 테이블과의 관계를 연결함

module.exports = db;
profile
https://brgndy.me/ 로 옮기는 중입니다 :)

0개의 댓글