본문 바로가기
공부/express

[Express] sequelize 사용법 (ORM)

by 웅대 2024. 5. 12.
728x90
반응형

https://growth-coder.tistory.com/274

 

[express] express 웹 서버 기초

pacakage.json 생성npm init 명령어로 package.json을 만들어준다. package.json에는 프로젝트가 사용 중인 패키지의 정보가 담겨있다.package.json 문서를 통해 패키지를 쉽게 관리할 수 있다. npm init npm init 명

growth-coder.tistory.com

지난 포스팅에서 Express 기초에 대해 알아보고 mysql 데이터베이스와 연결하여 직접 SQL 쿼리문을 날려 데이터를 조작해보았다.

 

이번 포스팅에서는 sequelize 패키지를 사용하여 ORM으로 데이터베이스의 데이터에 접근해보려고 한다.

 

간단하게 Team 테이블과 1:N 관계를 가지고 있는 User 테이블을 사용하여 sequelize를 사용해보자.

패키지 설치

npm init으로 package.json 파일을 생성하자.

npm init

 

다음 패키지를 설치한다.

npm install express mysql2 nodemon sequelize sequelize-cli

 

이전 포스팅에서는 mysql 패키지를 사용했는데 sequelize에서 에러가 발생하여 mysql2로 변경하였다.

 

package.json에서 scripts.start와 type을 작성해준다.

{
  "name": "sequel-commonjs",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start" : "nodemon index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.19.2",
    "mysql2": "^3.9.7",
    "nodemon": "^3.1.0",
    "sequelize": "^6.37.3",
    "sequelize-cli": "^6.6.2"
  },
  "type" : "commonjs"
}

 

이전 포스팅에서는 ES Module을 사용했는데 sequelize에서 기본적으로 생성해주는 코드가 commonJS로 이루어져 있어서 commonJS로 진행하려고 한다. 

 

위에서는 package.json에 "type": "commonjs"를 작성해줬지만 commonjs는 기본 값이라서 굳이 작성해주지 않아도 된다.

데이터베이스 세팅

우선 데이터베이스 설정을 위해 database 폴더를 만들고 그 안으로 이동한 후 npx sequelize init 명령어를 사용한다.

 

mkdir database
cd database
npx sequelize init

 

npx sequelize init 명령어를 사용하면 그 안에 config, migrations, models, seeders 폴더가 생긴다.

 

이 중 config 폴더 내부의 config.json에서 데이터베이스 설정을 변경할 수 있다.

 

config.json을 보면 아래와 같이 development, test, production 환경 별로 설정을 다르게 할 수 있다.

 

{
  "development": {
    "username": "root",
    "password": null,
    "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"
  }
}

 

development에서 mysql에 설정되어 있는 user 정보와 데이터베이스 정보를 입력하자.

 

sequelize 사용법을 익히는 것이 목적이니까 develpment에만 데이터베이스를 연결해서 테스트 해 볼 예정이다.

{
  "development": {
    "username": "root",
    "password": "0000",
    "database": "sequelize_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"
  }
}

 

각자 로컬에 존재하는 데이터베이스 정보를 입력하면 된다.

 

직접 로컬 데이터베이스를 생성해도 되지만 sequelize-cli를 사용하면 쉽게 데이터베이스를 생성할 수 있다.

 

config/config.json에 원하는 데이터베이스 설정을 하고 아래 명령어를 입력하면 데이터베이스를 생성해준다.

 

npx sequelize db:create

 

이제 models/ 폴더 내부의 index.js를 수정해보자.

 

 

모델 세팅 (테이블 세팅)

우리는 ORM을 사용하여 자바스크립트에서 객체 형식으로 데이터를 다룰 예정이다.

 

먼저 models/index.js 파일을 다음과 같이 수정한다.

 

<models/index.js>

const Sequelize = require('sequelize');
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;
module.exports = db;

 

이제 Team 모델을 만들어보자.

 

Model을 만드는 방법은 Model Definition과 Model Extending이 있다.

 

이 중 Model Extending을 사용해보자.

 

Sequelize.Model을 상속받아서 구현하면 된다.

 

<./models/Team.js>

const {Sequelize, DataTypes, Model} = require('sequelize')

module.exports = class Team extends Model{
    static init(sequelize){
        return super.init({
            name: {
                type: DataTypes.STRING,
                allowNull: false
            }
        }, 
        {
            sequelize,
            timestamps: true, // column에 자동으로 createdAt, updatedAt이 생성 
            modelName: 'Team', // 모델 이름
            tableName: 'teams', // 데이터베이스 테이블 이름
            paranoid: false, // true로 하면 데이터베이스에서 실제로 삭제하지 않고 deletedAt column을 사용해서 삭제
            charset: 'utf8mb4', // 캐릭터 셋 
            collate: 'utf8mb4_general_ci' // 정렬 기준
        })
    }
}

 

첫 번째 객체엔 컬럼 설정 정보, 두 번째 객체엔 추가적인 설정 정보를 입력하면 된다.

 

init 메소드를 static으로 만들어서 models/index.js에서 이 init을 호출할 예정이다.

 

User도 만들어보자.

<./models/User.js>

const {Sequelize, DataTypes, Model} = require('sequelize')

module.exports = class User extends Model {
    static init(sequelize){
        return super.init({
            name:{
                type: DataTypes.STRING,
                allowNull: false
            },
            age: {
                type: DataTypes.INTEGER,
                allowNull: false
            }
        },
        {
            sequelize,
            timestamps: true, // column에 자동으로 createdAt, updatedAt이 생성 
            modelName: 'User', // 모델 이름
            tableName: 'users', // 데이터베이스 테이블 이름
            paranoid: false, // true로 하면 데이터베이스에서 실제로 삭제하지 않고 deletedAt column을 사용해서 삭제
            charset: 'utf8mb4', // 캐릭터 셋 
            collate: 'utf8mb4_general_ci' // 정렬 기준
        })
    }
}

 

이제 models/index.js 파일을 수정할 차례이다.

 

<models/index.js>

// Sequelize 객체 가져오기
const Sequelize = require('sequelize');

// model 가져오기
const Team = require('./team')
const User = require('./user')

// config 가져오기
const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];

// db 설정
const db = {};
const sequelize = new Sequelize(config.database, config.username, config.password, config);
db.sequelize = sequelize;
db.Team = Team
db.User = User

// association 설정
// Team과 User는 1:N 관계
Team.init(sequelize)
User.init(sequelize)
Team.hasMany(User)
User.belongsTo(Team)

module.exports = db;

 

모델들을 서로 1:N으로 연결시킨 모습을 볼 수 있다.

 

이렇게 모델들을 만들었으면 이 모델들과 매핑되는 테이블을 생성할 차례이다.

 

이 테이블은 직접 생성하는게 아니라 데이터베이스를 연결할 때 생성된다.

 

이제 index.js에서 데이터베이스를 연결하는 코드를 작성해보자.

 

const express = require('express')
const {sequelize, Team, User} = require('./database/models')
sequelize.sync({force: false})
.then(()=>{
    console.log('데이터베이스 연결 성공')
})
.catch((err)=>{
    console.log(err)
})
const app = express()
app.listen(3001, ()=>{
    console.log("3001 포트 연결")
})

 

sequelize.sync를 실행하면 Model에 매핑되는 테이블들이 생성된다.

 

연관 관계

Team과 User는 1:N 매핑을 이루고 있고 데이터를 삽입할 때 이러한 연관 관계를 삽입하는 방법을 알아보자.

 

1. method 사용

async function init(){
    const team = await Team.create({
        name: "첫 번째 팀"
    })
    const user = await User.create({
        "name" : "김철수",
        "age" : 12
    })
    team.addUser(user)
}

Model의 add모델 메소드를 사용해서 연관 관계를 매핑할 수 있다.

 

2. foreign key 사용

async function init2(){
    const team = await Team.create({
        name: "첫 번째 팀"
    })
    const user = await User.create({
        "TeamId": team.id,
        "name" : "김철수",
        "age" : 12
    })

}

직접 foreign key를 넣어서 연관 관계를 매핑할 수 있다.

 

app.listen에서 서버가 실행될 때 위 함수를 사용해서 데이터를 넣어보자.

 

const express = require('express')
const {sequelize, Team, User} = require('./database/models')
sequelize.sync({force: false})
.then(()=>{
    console.log('데이터베이스 연결 성공')
})
.catch((err)=>{
    console.log(err)
})
const app = express()
app.listen(3001, ()=>{
    console.log("3001 포트 연결")
    init2()
})

async function init(){
    const team = await Team.create({
        name: "첫 번째 팀"
    })
    const user = await User.create({
        "name" : "김철수",
        "age" : 12
    })
    team.addUser(user)
}
async function init2(){
    const team = await Team.create({
        name: "첫 번째 팀"
    })
    const user = await User.create({
        "TeamId": team.id,
        "name" : "김철수",
        "age" : 12
    })

}

데이터베이스의 User 테이블에 추가된 User의 TeamId가 잘 매핑되었는지 확인해보자.

 

create 외의 다양한 쿼리들은 아래 공식 문서를 참고하면 쉽게 구현할 수 있다.

https://sequelize.org/docs/v6/core-concepts/model-querying-basics/

 

Model Querying - Basics | Sequelize

Sequelize provides various methods to assist querying your database for data.

sequelize.org

 

728x90
반응형

댓글