gengminy
갱미니의 코딩일지
gengminy
전체 방문자
오늘
어제
  • 분류 전체보기 (61)
    • 🚀 프로젝트 (16)
      • 🎸 고스락 티켓 (4)
      • 🌞 내친소 (5)
      • 🥁 두둥 (7)
    • 📡 백엔드 (31)
      • 🌱 Spring Boot (13)
      • 🐱 Nest.js (10)
      • ⭐ Node.js (8)
    • 🏭 Infra (11)
      • ⚙ 준비를 위한 준비 (2)
      • 🥑 AWS (3)
      • 🐳 Docker (3)
      • ⚡ Github Actions (3)
    • 🌊 프론트엔드 (1)
      • 🌌 React.js (1)
    • 😎 주저리 (2)

블로그 메뉴

  • 💻Github
  • 📸Instagram
  • ✨Blog

공지사항

인기 글

태그

  • oauth2
  • AWS
  • 도커
  • 슬랙알림
  • nodejs
  • github
  • nest
  • OAuth
  • nestjs
  • SlackAPI
  • 네스트
  • JSON
  • 스프링
  • JWT
  • Spring
  • 깃헙액션
  • GithubActions
  • springboot
  • docker
  • 스프링부트

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
gengminy
📡 백엔드/⭐ Node.js

[Nodejs] Sequelize 로 SQL 데이터베이스 연동하기

📡 백엔드/⭐ Node.js

[Nodejs] Sequelize 로 SQL 데이터베이스 연동하기

2022. 5. 21. 01:21

✅ Sequelize

ORM으로 분류되는 라이브러리

즉 자바스크립트 객체와 데이터베이스의 릴레이션을 매핑해주는 도구이다

 

📝ORM(Object- relational Mapping)

객체 관계 매핑

데이터베이스와 객체지향 프로그래밍 언어 사이에

호환되지 않는 데이터를 변환하는 프로그래밍 기법

객체지향 언어에서 사용할 수 있는 가상 객체 DB를 구축하는 방법이다

 

 

✅ Sequelize 의존성 추가 및 초기 세팅

npm i sequelize sequelize-cli mysql2
npx sequelize init

 

🔨 config/config.json

 

{
  "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"
  }
}

.env 의 process.env.NODE_ENV 의 값에 따라 db를 지정할 수 있다 (development, test, production)

username 와 password 를 각각 MySQL 계정에 맞게 수정해준다

database 는 nodejs 로 바꿔준다

  "development": {
    "username": "root",
    "password": MYPASSWORD,
    "database": "nodejs",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },

 

 

✅ models 폴더에 모델 추가

 

🔨 models/user.js

const Sequelize = require('sequelize');

module.exports = class User extends Sequelize.Model{
    static init(sequelize){
        return super.init({
            email: {
                type: Sequelize.STRING(40),
                allowNull: false,
                unique: true,
            },
            ...
            provider: {
                type: Sequelize.STRING(10),
                allowNull: false,
                defaultValue: 'local',
            },
        }, {
            sequelize,
            timestamps: true,
            underscored: false,
            modelName: 'User',
            tableName: 'users',
            paranoid: true,
            charset: 'utf8',
            collate: 'utf8_general_ci',
        });
    }

    static associate(db){}
};

super.init 메소드에서는 테이블 설정을

associations 메소드에서는 다른 모델과의 관계를 적는다

 

super.init 메소드의 첫번째 인수는 테이블 칼럼에 대한 설정이고

두번째 인수는 테이블 자체에 대한 설정이다

 

MySQL 의 자료형은 Sequelize 의 자료형으로 다음과 같이 바뀐다

MySQL Sequelize
VARCHAR(100) STRING(100)
INT INTEGER
TINYINT BOOLEAN
DATETIME DATE
INT UNSIGNED INTEGER.UNSIGNED
NOT NULL allowNull: false
UNIQUE unique: true
DEFAULT now() defaultValue: Sequelize.NOW

 

테이블 자체 옵션은 아래와 같다

sequelize db.sequelize 객체를 넣어야함
timestamps true - createAt, updatedAt 컬럼을 추가하며 자동으로 시간 입력
false - 추가하지 않음
underscored true - 스네이크 케이스를 사용
false - 카멜 케이스를 사용 (기본값)
modelName 모델 이름 설정
tableName 테이블 이름 설정
관행적으로 모델 이름을 소문자 + 복수형으로 만듬
(모델 User -> 테이블 users)
paranoid true - deletedAt 칼럼을 추가
로우를 조회할 때 deletedAt: null 인 값만 조회함
나중에 복원해야 할 필요가 있을 때 사용
false - 추가하지 않음
charset / collate utf8 / utf8_general_ci 를 사용해야
한글을 입력할 수 있다
이모티콘까지 입력하고 싶다면
utf8mb4 / uft8mb4_general_ci 사용

 

🔨 models/index.js

const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];
const User = require('./user');

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

db.sequelize = sequelize;
db.User = User;

User.init(sequelize);

//User.associate(db);

module.exports = db;

원래 코드를 지우고 다음과 같이 바꾸어 User 모델과 데이터베이스를 연결했다

 

 

✅ 관계 정의하기(JOIN)

 

📝 1:N 관계 - hasMany, belongsTo

 

예를 들어 사용자의 정보에 대한 users 테이블과

게시글 정보에 대한 posts 테이블이 있을 때

 

사용자는 게시글을 여러개 적을 수 있지만

게시글을 작성한 사용자가 여러 명일 수는 없다 (일반적으로)

즉, User : Post = 1 : N

 

🔨 models/user.js

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

// 또는

static associate(db){
  db.User.hasMany(db.Post);
}

🔨 models/post.js

static associate(db){
    db.Post.belongsTo(db.User);
}

// 또는

static associate(db){
    db.Post.belongsTo(db.User, { foreignKey: 'writer', targetKey: 'id'});
}

foreignKey 를 지정하지 않는다면

user(모델명) + 기본키(id) 가 합쳐진 UserId 가 foreignKey 로 생성된다

 

📝 1:1 관계 - hasOne, belongsTo

 

만약 사용자 정보를 담는 Info 모델이 있다고 가정하면

아래와 같이 적을 수 있다

즉, User : Info = 1 : 1

db.User.hasOne(db.Info, { foreignKey: 'UserId', sourceKey: 'id'});
db.Info.belongsTo(db.User, { foreignKey: 'UserId', targetKey: 'id'});

 

📝 N:M 관계 - hasOne, belongsTo

 

Post 모델과 Hashtag 모델이 있다고 하면

아래와 같이 표현 가능하다

Post <-> PostHashtag <-> Hashtag

db.Post.belongsToMany(db.Hashtag, { through : 'PostHashtag' });
db.Hashtag.belongsToMany(db.Post, { through : 'PostHashtag' });
Post PostHashtag Hashtag
id content postId hashtagId id title
1 #cpp #python 1 1 1 cpp
2 #gengminy 1 2 2 pytyon
3 #javascript 2 1 3 javascript
  3 3  

 

N:M 관계에서는 데이터를 조회할 때 여러 단계를 거쳐야 한다

자동으로 만들어진 모델(PostHashtag)도 다음과 같이 접근 가능하다

db.sequelize.models.PostHashtag

 

 

✅ 생성한 모델을 데이터베이스 및 서버와 연결하기

 

💻 console

npx sequelize db:create

// Sequelize CLI [Node: 16.10.0, CLI: 6.4.1, ORM: 6.19.2]

// Loaded configuration file "config\config.json".
// Using environment "development".
// Database database_development created.

🔨 app.js

const { sequelize } = require('./models');
...
sequelize.sync({ force: false })
    .then(() => {
        console.log('database connected!');
    })
    .catch((err) => {
        console.error(err);
    })

반드시 config/config.json 에서 데이터베이스 비밀번호를 설정해주도록 한다

IF NOT EXISTS 가 포함된 테이블 생성 쿼리문을 날려

테이블이 없어도 자동으로 테이블을 생성해준다

저작자표시 (새창열림)

'📡 백엔드 > ⭐ Node.js' 카테고리의 다른 글

[Nodejs] passport 모듈로 로컬 로그인 전략 구현하기  (0) 2022.05.24
[Nodejs] Sequelize 로 SQL 쿼리 사용하기  (0) 2022.05.21
[Nodejs] Router 객체로 라우팅 파일 분리  (0) 2022.05.17
[Nodejs] 미들웨어의 사용과 자주 쓰이는 미들웨어  (0) 2022.05.16
[Nodejs] express 서버 열기  (0) 2022.05.15
    '📡 백엔드/⭐ Node.js' 카테고리의 다른 글
    • [Nodejs] passport 모듈로 로컬 로그인 전략 구현하기
    • [Nodejs] Sequelize 로 SQL 쿼리 사용하기
    • [Nodejs] Router 객체로 라우팅 파일 분리
    • [Nodejs] 미들웨어의 사용과 자주 쓰이는 미들웨어
    gengminy
    gengminy
    코딩

    티스토리툴바

    개인정보

    • 티스토리 홈
    • 포럼
    • 로그인

    단축키

    내 블로그

    내 블로그 - 관리자 홈 전환
    Q
    Q
    새 글 쓰기
    W
    W

    블로그 게시글

    글 수정 (권한 있는 경우)
    E
    E
    댓글 영역으로 이동
    C
    C

    모든 영역

    이 페이지의 URL 복사
    S
    S
    맨 위로 이동
    T
    T
    티스토리 홈 이동
    H
    H
    단축키 안내
    Shift + /
    ⇧ + /

    * 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.