Home sequelize 모듈 - 01
Post
X

sequelize 모듈 - 01

ORM (Object-Relational Mapping)

Object-Relational Mapping, 객체-관계 매핑

ORM은 객체와 RDB의 데이터를 자동으로 매핑(연결)해주는 것을 말합니다.

예를 들면, 객체 지향 언어에서는 모델을 정의할 때 Class를 사용하고, RDB에선 Table을 사용합니다.

이 떄, 객체 지향 언어로 된 Class를 RDB의 Table와 연결시켜주는 것으로 SQL문이 아닌 객체 지향 코드로 작성할 수 있습니다.

  • 장점

    • 객체 지향적인 코드로 작성하므로 직관적
    • 재사용 및 유지보수의 편리성 증가

Sequelize

Sequelize는 Postgres, MySQL, MariaDB, SQLite, Microsoft SQL Server를 지원하는 Promise 패턴 기반의 Node.js ORM입니다

Spring의 JPA/Hibernate, Django의 Django ORM

ORM의 특징은 특정 DB에 종속되지 않는다는 것입니다.

즉, DB와 커넥션만 연결되면 어떤 DB를 사용하던지 상관없이 동일한 메서드로 쿼리 수행이 가능합니다.

  • 설치

    1
    
    npm i sequelize
    

sequelize과 Mysql 연결

Sequelize를 사용하기 위해서는 Postgresql , MySQL , MSSQL, SQLite 등의 RDB가 시스템에 설치되어있어야 합니다.

Mysql을 연결해보겠습니다.

1
npm i mysql2

sequelize-cli

sequelize-cli 모듈은 sequelize를 조금 더 효율적으로 사용하기 위한 뼈대를 구축해줍니다.

1
npm i sequelize-cli

설치가 완료되면 sequelize 명령어를 실행할 수 있습니다.

1
sequelize init

명령 실행하면 config, models, migrations, seeders 폴더가 생성됩니다.


models/index.js

sequelize-cli가 자동으로 생성해주는 코드는 에러가 발생하기도 하고 불필요한 부분이 많아 간단하게 새로 작성해줍니다.

참고 글 : Sequelize - Getting Started

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const Sequelize = require("sequelize");
const env = process.env.NODE_ENV || "development"; // 지정된 환경변수가 없으면 'development'로 지정

const config = require("../config/config.json")[env];
// config.json 파일에 여러 변수명으로 객체를 생성하여 DB 설정을 관리합니다.
// config객체의 env변수(development)키 의 객체값들을 불러옵니다.
// 즉, 데이터베이스 설정을 불러오는 것

const db = {};

// new Sequelize를 통해 MySQL 연결 객체를 생성합니다.
const sequelize = new Sequelize(
  config.database,
  config.username,
  config.password,
  config
);

// 연결객체를 나중에 재사용하기 위해 db.sequelize에 넣어줍니다.
db.sequelize = sequelize;

module.exports = db;

config/config.json

DB 설정을 관리하는 파일입니다.

사용할 DB 정보를 입력해줍니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
  "development": {
    "username": "root",
    "password": null,
    "database": "database_production",
    "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에서 모델을 정의하는 데 사용되는 메서드에는 defineinit이 있습니다.

Model에서 클래스로 구현할 것이므로 init 메서드를 사용해보겠습니다.

define은 sequelize 객체를 직접 호출하여 모델을 정의합니다.
init은 모델 클래스를 확장한 후에 호출하여 모델을 초기화합니다.

  • 주요 매개변수

    • attributes : 테이블의 열(컬럼)을 정의하는 객체입니다.

      각 열은 이름, 데이터 유형, 제약 조건 등을 포함합니다.

      • type : 데이터 타입 명시
      • primaryKey : 기본 키 설정
      • allowNull : Null 허용 여부
      • unique : 중복 값 저장 여부
      • autoIncrement : Auto Increase 기능 사용 여부
      • defaultValue : 기본 값 명시
      • validate : 유효성 검사 옵션
    • options : 모델의 추가적인 설정을 지정하는 객체입니다.

      • modelName : 모델 이름 명시적 설정
      • tableName : 테이블 이름 명시적 설정
      • freezeTableName : true 설정 시, 모델이름 변환 X, 지정한 이름 사용
      • underscored : true 설정 시, 카멜케이스 대신 스네이크케이스를 사용
      • timestamps : true 설정 시, created_at, updated_at 컬럼이 생성되며 데이터의 생성, 수정 시 시간이 자동으로 입력됩니다.
      • paranoid : true 설정 시, deletedAt 컬럼이 생성되며 지운 시각이 입력됩니다.
      • charset : 인코딩

models/users.js

models 폴더에 users.js 파일을 생성합니다.

class로 모듈화하고 import/export를 활용해 사용해보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// users.js
import { DataTypes, Model } from "sequelize";

class User extends Model {
  static init(sequelize) {
    return super.init(
      // 부모 객체의 init을 사용하므로 super.init 사용
      {
        user_id: {
          type: DataTypes.INTEGER,
          primaryKey: true,
          autoIncrement: true,
          allowNull: false,
          // unique
          // defaultValue
          // validate
        },
        password: {
          type: DataTypes.STRING(30),
          allowNull: false,
        },
      },
      {
        sequelize, // Sequelize 인스턴스
        timestamps: false, // true : created_at, updated_at 컬럼이 생성되며 데이터의 생성, 수정 시 시간이 자동으로 입력됩니다.
        paranoid: false // true : deletedAt 컬럼이 생성되며 지운 시각이 기록됩니다. ,
        underscored: true, // true : 카멜케이스 대신 스네이크케이스를 사용
        freezeTableName: true, // 모델이름 변환 X, 지정한 이름 사용
        modelName: "User", // 모델 이름 명시적 지정
        tableName: "users", // 테이블 이름 명시적 설정
      }
    );
  }
}

export default User;

sequelize의 자료형 (DataTypes)

sequelize의 자료형은 MySQL과 다르므로 확인 후 사용해야합니다.

참고 글 : Sequelize - Datetypes

sequelize-datatypes


models/index.js 수정

index.js 파일에 users.js 파일을 import한 후 연결해보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const Sequelize = require("sequelize");
const env = process.env.NODE_ENV || "development"; // 지정된 환경변수가 없으면 'development'로 지정

// ************* 추가된 부분 ***************
// 클래스를 불러온다.
import User from "./users.js";
// ****************************************

const config = require("../config/config.json")[env];
// config.json 파일에 여러 변수명으로 객체를 생성하여 DB 설정을 관리합니다.
// config객체의 env변수(development)키 의 객체값들을 불러옵니다.
// 즉, 데이터베이스 설정을 불러오는 것

const db = {};

// new Sequelize를 통해 MySQL 연결 객체를 생성합니다.
const sequelize = new Sequelize(
  config.database,
  config.username,
  config.password,
  config
);

// 연결객체를 나중에 재사용하기 위해 db.sequelize에 넣어줍니다.
db.sequelize = sequelize;

// ************* 추가된 부분 ***************
// 모델 클래스를 넣어줍니다.
db.User = User;

// 모델과 테이블 종합적인 연결이 설정된다.
User.init(sequelize);
// ****************************************

module.exports = db;

모델과 DB 동기화

sync()는 Promise를 반환하는 함수이며 이를 이용해 Model을 DB와 동기화 할 수 있습니다.

호출 시, Sequelize는 자동으로 DB에 대한 SQL 쿼리를 수행합니다.

이 떄, DB의 테이블만 변경합니다,

sync(options: object) 형태로 사용합니다.

  • options

    • 미설정 : 존재하지 않는 경우에만 테이블을 생성합니다.

    • force : true 설정 시, 테이블을 이미 존재하는 경우 먼저 삭제한 후 생성합니다.

      데이터도 같이 삭제됩니다.

    • alter : 테이블의 현재 상태를 확인한 후 모델과 일치하도록 변경합니다.

      데이터도 그대로 유지됩니다.


app.js

sequelize.sync() 를 이용하면 자동으로 모든 모델을 동기화할 수 있습니다.

app.js 파일에 index.js 파일을 import한 후 연결해보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import express from "express";
import "dotenv/config";

import db from "./models/index.js";
const app = express();

app.set("port", process.env.PORT || 8000);

try {
  await db.sequelize.sync();
  console.log("데이터베이스 연결됨.");
} catch (err) {
  console.log(err);
}

app.use(express.json()); // json 파싱
app.use(express.urlencoded({ extended: false })); // uri 파싱

app.get("/", (req, res) => {
  res.json({ message: "hello world" });
});

// 서버 실행
app.listen(app.get("port"), () => {
  console.log(app.get("port"), "번 포트에서 대기 중");
});

연결 테스트

sequelize-create-table-init-01

sequelize-create-table-init-02

에러 없이 users 테이블이 잘 생성된 것을 확인할 수 있습니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.