본문 바로가기
Back-End/🌿Express (nodeJS)

[Express] Sequelize로 MySQL 연결하기 (1) - 테이블 생성하기

by 코딩하는 동현😎 2022. 11. 6.

Sequelize 라이브러리

시퀄라이즈는 ORM의 한 종류입니다.

ORM은 객체와 데이터베이스의 릴레이션(명령어)를 매핑해주는 도구입니다.

쉽게 말해서 자바스크립트 객체를 ORM함수로 입력하면 ORM이 MySQL 명령어로 변역해서 실행해주는 것입니다.

꼭 mysql뿐만 아니라 다른 데이터베이스 언어와도 전부 호환 됩니다.

 

npm으로 설치

sequelize-cli는 (comand line interface)로 시퀄라이즈 명령어를 터미널로 실행하기 위한 패키지이고, mysql2는 MySQL과 ORM을 연결해주는 드라이버입니다.

mysql2이랑 MySQL이랑 헷갈리면 안됩니다. 별도로 설치해야합니다.

npm i express sequelize sequelize-cli mysql2

 

Sequelize 초기화

아래의 명령어를 실행해주면 config, models, migrations, seeders 폴더가 자동 생성됩니다

npx sequelize init

시퀄라이즈를 프로젝트와 연동

config, models, migrations, seeders 폴더가 생성됐는데, 그중 config와 model을 유심히 보겠습니다.

 


config/config.json

MySQL 서버에 대한 정보들을 작성하는 곳입니다.

여기서 MySQL 서버에 대한 정보들을 수정해서 작성하시면 됩니다.

{
  "development": {
    "username": "root",
    "password": "12345678",
    "database": "database_development",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "test": {
    "username": "root",
    "password": "12345678",
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "production": {
    "username": "root",
    "password": "12345678",
    "database": "database_production",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}

models/index.js

models 폴더는 객체들과 테이블 객체들이 있습니다.

index 이름은 기본이 되는 이름으로 참조할때 이름을 생략해도 참조가 됩니다.

예) 두 코드는 같은 코드입니다.

const index = require('./models')

const index = require('./models/index')

 

index.js 에서 sequelize랑 MySQL을 연결해서 sequlize객체를 만들고, db라는 json객체에 추가해줍니다.

그리고 db객체를 참조할수 있도록 exports해줍니다. (외부에서 의존성 주입 할 수 있도록)

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;

NODE_ENV는 development test production 중 하나로 설정하면 됩니다. (.env 파일)


app.js 추가 내용

models/index.js에서 sequelize객체를 담은 db를 export했습니다.

index라는 이름은 생략해도되므로  models/index 를 호출한것과 같습니다.

 

특수한 문법인데,

db = { a:x , b:y } 라고 하면 const { a } = db 라고 할때

a = x 가 됩니다.

즉 sequelize는 db안에 실려있던 sequelize객체가 저장되게 됩니다.

sync함수로 시작하고, force : false이면 서버를 실행할때마다 초기화하지 않습니다.

const { sequelize } = require('./models') // models/index.js

sequelize.sync({force : false})
	.then(() => {console.log('db ok')})
	.catch((err) => {console.log(err)})

테이블 생성하기

models/users.js

시퀄라이즈 init 했을때 생성됐던 models안에 테이블 이름과 같은(같지않아도 되지만 같으면 가독성이 올라감) js 파일을 생성해줍니다.

users 테이블을 만드는것을 예시로 하겠습니다.

시퀄라이즈의 모델을 상속받는 User 객체를 만들어주고, init(스키마 , 테이블 옵션) 함수를 정의합니다.

 

첫번째 인자로 스키마로, 아래와 같이 속성을 입력해줍니다.

id는 자동으로 생성되므로 따로 입력하지 않아도 됩니다.

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 : true,
            modelName : "User",
            tableName : "users",
            paranoid : false,
            collate : "utf8_general_ci",
            charset : "utf8",
        })
    }
};

두번째 인자는 테이블 옵션으로,  모델이름과 테이블이름(users)를 입력해줍니다.

timestamps는 객체가 만들어질때 시간을 기록하는 옵션으로 created_at 속성이 있으므로 false했습니다.

underscored 속성은 true -> created_at , false -> createdAt 으로 컬럼명이 설정됩니다.

 

나중에 User.init(sequelize); 해주고 실행시키면 자동으로 sql에 테이블이 생성됩니다.


관계정의하기

mysql는 관계형 데이터베이스로 테이들간에 관계가 있습니다.

관계의 유형엔 두 테이블의 1:1 , 1:N , N:M 관계가 있습니다.

 

1:1 관계에는 예를 들어서 사람테이블과 자기소개테이블 (한사람이 하나의 자기소개만 입력할수 있다면)

 

1:N 관계에는 사람테이블과 댓글테이블 (한사람이 여러댓글 입력할 수 있으므로)

 

N:M 관계에는 계시물테이블과 해시태그테이블이 있습니다. (한 계시물에 여러 해시태그가 있기도, 한 해시태그를 포함하는 여러 테이블이 있기도 함)

 

두 테이블을 연결하기 위해선 외래키(foreignKey)로 정의할 수 있습니다.


1:N 관계의 예시

user테이블 말고도 comments(댓글) 테이블이 있다고 해봅니다.

그러면 1에 해당하는 테이블이 기준이 되는 테이블로 users.js의 User객체 내부에 아래 함수를 추가해줍니다.

기준이 되는 키가 users의 id이므로 sourceKey가 되고, 외래(공동키)키를 설정해줍니다.

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

 

N에 해당되는 comments 테이블에선 Comment 객체 내부에 함수를 아래와 같이 입력합니다.

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

models/index.js

index.js 파일에 아래 내용을 추가해줘서 완성시키면 두 테이블의 관계 정의까지 끝납니다.

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);

const User = require('./user')
const Comment = require('./comment')

// 테이블 생성
User.init(sequelize);
Comment.init(sequelize);

//db에 객체들 추가
db.User = User
db.Comment = Comment

//서로의 관계 정의
User.associate(db);
Comment.associate(db);


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

// 이 파일을 호출하면 모든것을 담은 db객체를 쓸수 있음
module.exports = db;

1:1 관계에서는 아래와 같이 하시면 됩니다.

 

db.User.hasOne(db.Comment , {foreignKey : 'commenter' , sourceKey : 'id'});

 

db.Comment.belongsTo(db.Comment , {foreignKey : 'commenter' , sourceKey : 'id'});

 

다음포스트에서는 sql 쿼리입력하는 법 등등 포스팅 하겠습니다!

반응형

댓글