Node.js에서의 CRUD(1)

윤태호·2023년 5월 28일
0

Node.JS

목록 보기
2/2

Node.js에서는 어떻게 했더라??

필자가 첫 서버를 배운 것이 바로 Node.js였습니다. 하지만 작년 11월쯤...그리고 개인적으로 Java+SpringBoot처럼 MVC 패턴 및 객체지향언어로 아키텍쳐가 갖춰져있는 것을 선호했기에, 그 뒤로 Node를 해본적이 없었습니다.
그래서 기억이 가물가물 하지만...고수는 장비 탓을 하지 않고, 문서화를 통해 확실히 다시 복습하기 위해 글을 남깁니다 ㅎㅎ

Sequelize and Model

Node도 JPA와 같이 ORM이 존재하며 그게 바로 Sequelize 입니다. 그리고 Models는 Entity와 같이 DB에 매핑을 하기위한 클래스로 선언됩니다.
Package 설치와 같은 것들은 생략하겠습니다!!

Model을 어떻게 작성해나가는지 살펴봅시다.
사실 Sequelize는 Spring+JPA보다 덜 비정형화 되어있기 때문에 개발자마다 다양하게 코드를 짜나가는 것 같습니다.
필자는 두 가지 방식으로 짰었습니다.

  • 정적인 형태의 Model
  • Model Class를 상속받는 Model
  1. 정적인 형태의 Model
module.exports = (sequelize,DataTypes) => const User {
sequelize.define(
  'User',{
		Field 정의
},
{	associate(models){
		외래키 및 다른 Model과의 관계 정의}
}
return User;
}
  1. Model Class를 상속받는 Model
module.exports = (sequelize,DataTypes => 
class User extends Model {
	static asssociate(models){
    }
},
User.init {
	Field 정의
}
return User;
}

둘 중에 어떤 것이 더 옳은 것은 없습니다.

  • 차이점은 정적인 Model은 sequelize.define() 메소드를 통해 init과 같은 Model의 초기화를 진행합니다.
  • 반면 Model Class를 상속받으면, init을 통해 초기화를 진행하며, 이 과정에서 sequelize 객체를 넘겨줘야합니다!!

이렇게 Model들을 작성하고, config를 잘 작성했다면 npm run을 하게 된다면 데이터베이스 연결이 잘 될 것입니다.

index.js와 config 및 그 외 설명

너무 간단하게 설명하고 넘어가는 것 같기에, Model 외에 필요한 것과 코드를 남기며 설명을 마칠려고 합니다.

index.js

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

const db = {};

// 모델 파일을 읽어서 초기화
db.Post =  require('./Post')(sequelize, Sequelize.DataTypes)
db.Member =  require('./Member')(sequelize, Sequelize.DataTypes)
db.Reply =  require('./Reply')(sequelize, Sequelize.DataTypes)

// 모델 간의 관계 설정
Object.keys(db).forEach((modelName) => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

// sequelize 객체와 모델을 연결
db.sequelize = sequelize;
db.Sequelize = Sequelize;


module.exports = db;

위의 코드를 잠시 해석하고 넘어가자

  • 첫 문단은 새로운 seqelize 객체에 config에 있는 db 정보를 넘겨주는 과정입니다.
  • 그 다음 db라는 const를 선언하여, db const에 각 Model을 읽어 초기화 시켜주는 과정입니다.(이 과정도 fs,readdirSync,foreach를 통해 읽어낼 수 있습니다.)
  • db에 맵핑한 Model들을 순회하며 associate 즉 연관관계를 설정합니다.
  • 마지막으로 sequelize와 Model을 연결합니다.

config.json

{
  "development": {
    "username": "test",
    "password": "1234",
    "database": "test",
    "host": "localhost",
    "port":"3306",
    "dialect": "mysql",
    "timezone": "+09:00"
  },
  "test": {
  	"username": "test",
    "password": "1234",
    "database": "test",
    "host": "localhost",
    "port":"3306",
    "dialect": "mysql",
    "timezone": "+09:00"
  },
  "production": {
  	"username": "test",
    "password": "1234",
    "database": "test",
    "host": "localhost",
    "port":"3306",
    "dialect": "mysql",
    "timezone": "+09:00"
  }
}

여기서 다른 것보다 2개만 짚고 넘어가겠습니다.

  • Springboot application.yml과 다르게 host와 port를 분리해서 작성해줘야합니다. localhost:3306 이렇게 했다가...1시간 동안 오류 잡았습니다 ㅠㅠ
  • timezone을 설정하여 현재 우리나라 시간과 맞춰 주시는게 편합니다. 안맞추시면 createAt,deletedAt 들이 안맞을 수 있습니다.

내 Model

const { Model } = require('sequelize');
const models = require('../models')

module.exports = (sequelize, DataTypes) => {
  class Member extends Model {
    static associate(models) {
      Member.hasMany(models.Post, {
        foreignKey: 'member_id',
        onDelete: 'cascade'
      });
    };
    
  }
  Member.init(
    {
      member_id: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        comment: '고유 ID',
        autoIncrement: true,
        allowNull: false
      },
      id: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: true
      },
      name: {
        type: DataTypes.STRING,
        allowNull: false
      },
      email: {
        type: DataTypes.STRING,
        allowNull: true
      },
      password: {
        type: DataTypes.STRING,
        allowNull: false
      },
      birthday: {
        type: DataTypes.STRING,
        allowNull: false
      }
    },
    {
      sequelize,
      modelName: 'Member',
      tableName: 'member',
      charset: 'utf8',
      collate: 'utf8_general_ci',
      timestamps: true,
      paranoid: true
    }
  );

  return Member;
};

필자는 위처럼 코드를 작성했습니다.

  • 상관관계 및 필요한 메서드나 Field 이름들은 찾아보시며 진행하시길 바랍니다!!!!
  • paranoid 및 timestamps를 활용하면 softdelete도 가능합니다 ㅎㅎ


잘 생성되었고, DB와 연결이 성공했다는 로그를 마지막으로 글을 마치겠습니다.

글을 마무리 지으며

Sequelize에 대해 자세히 적을까 고민했지만, 굳이 이미 너무 잘 알려져있는 블로그들도 많기에, 필요하다 생각하고 복습한다는 생각으로 글을 적었습니다.
다음 글은 어떻게 query를 생성했고, Router 처리를 어떻게 진행하였는지 적고자 합니다!!!
Node.js는 짧고 필요한것만 적을 예정입니다..ㅎㅎ

profile
성장하는것을 제일 즐깁니다.

0개의 댓글