데이터베이스 MySQL세팅하기, 시퀄라이즈 모델 만들기(2/2)

제이밍·2021년 8월 29일
2

Sequelize

MySQL 작업을 쉽게 할 수 있도록 도와주는 라이브러리가 있는데, 바로 시퀄라이즈(Sequelize)이다.

Sequelize를 사용하는 이유

시퀄라이즈를 쓰는 이유는 자바스크립트 구문을 알아서 SQL로 바꿔주기 때문이다. 따라서 SQL 언어를 직접 사용하지 않아도 자바스크립트만으로 MySQL을 조작할 수 있고, SQL을 몰라도 MySQL을 어느 정도 다룰 수 있게 된다.

sequelize 설치

데이터베이스(MySQL) 설치가 완료 되었다면 sequelize, sequelize-cli, mysql2 npm을 설치해줍니다.

npm i sequelize sequelize-cli mysql2

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

sequelize init 초기세팅

npx sequelize init

sequelize init을 하게 되면 config, migrations, medels, seeders 라는 초기화 폴더가 생성된다.

 config/config.json
{
  "development": {
    "username": "root",
     // sql 설치할때 세팅한 비밀번호를 입력해 준다.
    "password": "",
     // 데이터 베이스 이름 설정
    "database": "react-nodebird",
     //기본 localhost
    "host": "127.0.0.1",
    "port": "3306",
    "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"
  }
}
//models/index.js
const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];
const db = {};

//아래 설정을 통해 sequelize 가 노드랑 sql을 연결해준다.
//연결에 성공하면 sequelize에 연결정보가 담기게 된다. 
const sequelize = new Sequelize(config.database, config.username, config.password, config);

Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

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

module.exports = db;

Sequelize는 시퀄라이즈 패키지이자 생성자이고 config/config.json에서 데이터베이스 설정을 불러온 후 new Sequelize를 통해 MySQL 연결 객체를 생성한다.

sequelize 모델 만들기

이 완료된 후, models에 추가되는 파일들은 곧 sql의 테이블이 된다.

먼저 User, post 테이블을 세팅해보자.

//models/user.js
module.exports = (sequelize, DataTypes)=>{
    const User = sequelize.define('User', { // MySQL에는 users라는 테이블 생성
        // id는 mysql에서 자동으로 생성되기 때문에 넣어줄 필요 없다.
        // id: {},
        email: {
            type:DataTypes.STRING(30), 
           // 자주사용되는 자료형 STRING, TEXT, BOOLEAN, INTEGER, FLOAT, DATETIME
            allowNull: false, //필수값
            unique: true //고유값
        },
        nickname: {
            type:DataTypes.STRING(30),
            allowNull: false, //필수값
        },
        password: {
            // 패스워드는 암호화를 하기 때문에 넉넉하게 잡아주는 것이 좋다. 
            type:DataTypes.STRING(100),
            allowNull: false, //필수값
        },
    },{
        // 한글을 쓸수 있게 해준다.(한글 저장)
        charset: 'utf8',
        collate: 'utf8_general_ci' 
    });
    User.associate = (db) => {};
    return User;
}
// models/post.js
module.exports = (sequelize, DataTypes)=>{
    const Post = sequelize.define('Post', { // MySQL에는 Posts라는 테이블 생성
        content: {
          	// TEXT로 지정할지 글자수에 제한이 없다.
            type: DataTypes.TEXT,
            allowNull:false,
        },
    },{
        // 한글과 이모티콘을 쓸수 있게 해준다.(한글, 이모티콘 저장)
        charset: 'utf8mb4',
        collate: 'utf8mb4_general_ci',
    });
    Post.associate = (db) => {};
    return Post;
}

sequelize 관계설정

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

//models/user.js
    User.associate = (db) => {
        // User은 post와 comment를 여러개 가질 수 있다.
        db.User.hasMany(db.Post);
        db.User.hasMany(db.Comment);
        db.User.belongsToMany(db.Post,{ through: 'Like' ,  as: 'Liked'});
        db.User.belongsToMany(db.User,{ through: 'Follow', as:'Followers', foreignKey: 'FollowingId'})
        db.User.belongsToMany(db.User,{ through: 'Follow', as:'Followings', foreignKey: 'FollowerId'})
    };

db.User.belongsToMany(db.User,{ through: 'Follow', as:'Followings', foreignkey: 'followerId'})
through 는 테이블 이름을, foreignkey는 컬럼이름을 바꾸어 준다.

//models/post.js
    Post.associate = (db) => {
        db.Post.belongsTo(db.User); 
        db.Post.belongsToMany(db.Hashtag); //다대다 관계
        db.Post.hasMany(db.Comment);
        db.Post.hasMany(db.Image);
        db.Post.belongsToMany(db.User, { through: 'Like', as: 'Likers' });
    };

belongsToMany N:M 관계

다대다 관계를 설정해줄 경우 둘 사이에 중간 테이블이 생성되게 되며 이름을 설정해 줄 수 있다.
중간테이블이 있어 원활하게 검색 할 수 있다.

Sequelize 시퀄라이즈 sync + nodemon

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

//아래 설정을 통해 sequelize 가 노드랑 sql을 연결해준다.
//연결에 성공하면 sequelize에 연결정보가 담기게 된다. 
const sequelize = new Sequelize(config.database, config.username, config.password, config);

// 만들어논 Models을 불러와 sequilize 해준다.
db.Comment = require('./comment')(sequelize, Sequelize);
db.Hashtag = require('./hashtag')(sequelize, Sequelize);
db.Image = require('./image')(sequelize, Sequelize);
db.Post = require('./post')(sequelize, Sequelize);
db.User = require('./user')(sequelize, Sequelize);

Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

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

module.exports = db;

MySQL 연결하기

이제 시퀄라이즈를 통해 익스프레스 앱과 MySQL을 연결해야 한다.
app.js를 생성하고 익스프레스와 시퀄라이즈 연결 코드를 작성해봅시다.

//app.js
const express = require("express");
const postRouter = require("./routes/post");
const db = require('./models');
const app = express();

db.sequelize.sync()
.then(()=>{
  console.log('db 연결 성공 ')
})
.catch(console.error);

app.listen(3065, () => {
  console.log("서버 실행 중");
});

ERROR 발생 📍

npx sequelize db:create

🔥 error

$ node app

belongToMany는 through 옵션이 항상 요구되는것 같아 보인다.

// models/hashtag.js
    Hashtag.associate = (db) => {
        db.Hashtag.belongsToMany(db.Post);
    };
    
    
    Hashtag.associate = (db) => {
        db.Hashtag.belongsToMany(db.Post, {through: 'PostHashtag'});
    };

db 연결 성공!

작성한 코드에 별다른 오류가 없다면 시퀄라이즈가 성공되어 db연결이 완료된다.

CREATE TABLE IF NOT EXISTS
우리가 sequelize를 하면 테이블을 생성하게 되는데 이미 테이블이 있는경우 생성되지 않게 하기 위해 지정된 명령어 이다.

MySQL Workbench

MySQL Workbench 에서 생성한 database를 볼 수 있다.

nodemon

코드를 변경하고 나면 서버를 한번 껏다 켜는 과정을 필요로 하게 되는데 nodemon 을 사용하면 이런 귀찮은 과정을 생략할 수 있다.

npm i -D nodemon

command not found: nodemon

만약 위와같은 에러를 만났다면 sudo를 부쳐 다시 다운 받아 준다.

sudo npm i -D nodemon

Reference

Node.js 교과서 개정 2판

profile
모르는것은 그때그때 기록하기

0개의 댓글