๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
โš’ Backend/Node.js

[Node.js] Sequelize๋กœ C.R.U.D ๊ตฌํ˜„ํ•ด ๋ณด๊ธฐ (feat. MySQL)

by Fomagran ๐Ÿ’ป 2022. 7. 30.
728x90
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š” Foma ์ž…๋‹ˆ๋‹ค!

 

์˜ค๋Š˜์€ ์ €๋ฒˆ Sequelize ์ด๋ก  ๊ธ€์— ์ด์–ด์„œ C.R.U.D๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

(ํ˜น์‹œ ์ €๋ฒˆ ๊ธ€์„ ์•ˆ๋ณด์‹  ๋ถ„๋“ค์„ ์—ฌ๊ธฐ ์—์„œ ํ™•์ธํ•ด ์ฃผ์„ธ์š”)

 

๋ฐ”๋กœ ์‹œ์ž‘ํ• ๊ฒŒ์š”~


Install

 

express

 

npm install --save express

 

cors

 

npm install --save cors

 

sequelize

 

npm install --save sequelize

 

mysql2

 

npm install --save mysql2

Sequelize init

 

sequelize init

 

Sequelize๋ฅผ init ํ•ด์ฃผ๋ฉด ์ž๋™์œผ๋กœ config, migrations, models, seeders ์ด๋ ‡๊ฒŒ 4๊ฐœ์˜ ํด๋”๊ฐ€ ์ƒ๊ธธ๊ฑฐ์—์š”.

 

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” seeders๋Š” ์ด์šฉ๋˜์ง€ ์•Š์œผ๋‹ˆ ์‚ญ์ œํ•ด ์ค๋‹ˆ๋‹ค.

 

 

config.json

 

config.json์œผ๋กœ ๊ฐ€๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ๋˜์–ด ์žˆ์„๊ฑฐ์—์š”.

 

์—ฌ๊ธฐ๋Š” ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์˜ ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค.

 

์ด๋ฒˆ ๊ธ€์—์„  test์™€ production์€ ์‚ฌ์šฉ๋˜์ง€ ์•Š์œผ๋‹ˆ ์‚ญ์ œํ•ด์ฃผ๊ณ , ์•Œ๋งž๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•ด ์ค๋‹ˆ๋‹ค.

 

{
  "development": {
    "username": "์œ ์ €์ด๋ฆ„",
    "password": "ํŒจ์Šค์›Œ๋“œ",
    "database": "๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์ด๋ฆ„",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}

 

models/index.js

 

์•„๋ž˜์™€ ๊ฐ™์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์—ฐ๊ฒฐํ•ด ์ฃผ์„ธ์š”.

 

const { Sequelize, DataTypes } = require("sequelize");
const env = process.env.NODE_ENV || "development";

const config = require("../config/config.json")[env];

const db = {};

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

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

sequelize
  .sync({ force: false })
  .then(() => {
    console.log("๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ๋จ.");
  })
  .catch((err) => {
    console.error(err);
  });

module.exports = db;

 

app.js

 

app.js ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  ์ œ๋Œ€๋กœ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๊ฐ€ ์—ฐ๊ฒฐ๋˜์—ˆ๋Š”์ง€ ํ…Œ์ŠคํŠธ ํ•ด๋ด…๋‹ˆ๋‹ค.

 

const express = require("express");
const cors = require("cors");
const app = express();

var corOptions = {
  origin: "https://localhost:3000",
};

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

app.use(cors(corOptions));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

require("./models/index");

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

app.listen(app.get("port"), () => {
  console.log(app.get("port"), "๋ฒˆ ํฌํŠธ์—์„œ ๋Œ€๊ธฐ ์ค‘");
});

 

app.js๋ฅผ ์‹คํ–‰ ์‹œ์ผœ๋ณด๋ฉด

 

node app.js

 

์•„๋ž˜์™€ ๊ฐ™์ด ์ •์ƒ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๊ฐ€ ์—ฐ๊ฒฐ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 


Create a table

 

//npx sequelize migration:create --name ํ…Œ์ด๋ธ”์ด๋ฆ„
npx sequelize migration:create --name Users

 

์•„๋ž˜์™€ ๊ฐ™์ด migrations ํด๋”์— ํ˜„์žฌ ๋‚ ์งœ์™€ ์ง€์ •ํ•ด์ค€ ํ…Œ์ด๋ธ” ์ด๋ฆ„์„ ๊ฐ€์ง„ ํŒŒ์ผ์ด ์ƒ์„ฑ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

ํ•ด๋‹น ํŒŒ์ผ์—” ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑ๋˜์–ด ์žˆ๋Š”๋ฐ์š”.

 

up

logic for transforming into the new state

์ƒˆ๋กœ์šด ์–ด๋–ค ์ƒํƒœ๋กœ ๋ณ€ํ™”์‹œํ‚ฌ ๋กœ์ง์„ ์ž‘์„ฑ

 

down

logic for reverting the changes

๋ณ€ํ™”๋ฅผ ๋‹ค์‹œ ๋˜๋Œ๋ฆด ๋•Œ์˜ ๋กœ์ง์„ ์ž‘์„ฑ

 

์ด๋ผ๊ณ  ๊ณต์‹ ๋ฌธ์„œ์— ๋‚˜ํƒ€๋‚˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

module.exports = {
  async up (queryInterface, Sequelize) {
  },

  async down (queryInterface, Sequelize) {
  }
};

 

์•„๋ž˜์™€ ๊ฐ™์ด up์— Users ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•ด ์ฃผ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ปฌ๋Ÿผ์œผ๋ก  id,username,password๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค.

 

down์—” ์ƒ์„ฑํ•œ Users ํ…Œ์ด๋ธ”์„ ์‚ญ์ œํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

module.exports = {
  async up(queryInterface, Sequelize) {
    queryInterface.createTable("Users", {
      id: {
        type: Sequelize.INTEGER(11),
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
      },
      username: Sequelize.STRING(35),
      password: {
        type: Sequelize.STRING(20),
        allowNull: false,
      },
    });
  },

  async down(queryInterface, Sequelize) {
    queryInterface.dropTable("Users");
  },
};

Migrate

 

์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์ณ์„œ ์œ„์—์„œ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ง์ ‘ ๋งˆ์ด๊ทธ๋ ˆ์ดํŠธ ํ•ด์ค๋‹ˆ๋‹ค.

 

up ๋กœ์ง์„ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

(๋งˆ์ด๊ทธ๋ ˆ์ดํŠธ๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค์— ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ์ดํ•ดํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.)

 

sequelize db:migrate

 

์•„๋ž˜์™€ ๊ฐ™์ด config.json ํŒŒ์ผ์„ loaded ํ•ด migrate๋ฅผ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 

 

๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋กœ ์ด๋™ํ•˜์‹œ๋ฉด config.json์— ์„ค์ •ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ users ํ…Œ์ด๋ธ”๊ณผ id,username,password ์ปฌ๋Ÿผ๋“ค์ด ์ƒ์„ฑ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

๋งŒ์•ฝ migrate๋ฅผ ๋‹ค์‹œ ๋˜๋Œ๋ฆฌ๊ณ  ์‹ถ๋‹ค๋ฉด undo ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•ด ์ค๋‹ˆ๋‹ค.

 

undo๋ฅผ ์ž…๋ ฅํ•˜๋ฉด down ๋กœ์ง์ด ์‹คํ–‰๋˜์–ด ํ…Œ์ด๋ธ”์ด ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.

 

sequelize db:migrate:undo

 

ํ…Œ์ด๋ธ”์ด ์‚ญ์ œ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

๋ฐฉ๊ธˆ undo ๋ช…๋ น์–ด๋Š” ๋ฐ”๋กœ ์ด์ „์— ์‹คํ–‰๋œ migrate๋ฅผ ๋˜๋Œ๋ฆฌ๋Š” ๊ฒƒ์ธ๋ฐ์š”.

 

์ง€๊ธˆ๊นŒ์ง€ ํ•œ ๋ชจ๋“  ๋ช…๋ น์„ ๋˜๋Œ๋ฆฌ๊ณ  ์‹ถ๋‹ค๋ฉด undo:all์„ ์ž…๋ ฅํ•ด ์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

sequelize db:migrate:undo:all

Create a model

 

models ํด๋”์— User.js ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

 

 

ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•  ๋•Œ์™€ ๊ฐ™์ด ์ž‘์„ฑํ•ด ์ค๋‹ˆ๋‹ค.

 

๋‹ค๋งŒ ์ž๋™์œผ๋กœ createdAt, updatedAt ์ƒ์„ฑ์„ ํ•˜์ง€ ์•Š๋„๋ก timestamp: false๋กœ ์„ค์ •ํ•ด ์ค๋‹ˆ๋‹ค.

 

module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define(
    "User",
    {
      id: {
        type: DataTypes.INTEGER(11),
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
      },
      username: DataTypes.STRING(35),
      password: {
        type: DataTypes.STRING(20),
        allowNull: false,
      },
    },
    {
      timestamps: false,
    }
  );
  return User;
};

Create a controller

 

์ด์ œ User ํ…Œ์ด๋ธ”์— ์ƒ์„ฑ, ์‚ฝ์ž…, ์ˆ˜์ •, ์‚ญ์ œ๋ฅผ ์ง„ํ–‰ํ•  Controller๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

 

 

models ํด๋”์˜ index.js์— ๊ฐ€์„œ db์— users๋ฅผ ์ถ”๊ฐ€ํ•ด ์ค๋‹ˆ๋‹ค.

 

db.users = require("./User.js")(sequelize, DataTypes);

 

๋‹ค์‹œ UserController๋กœ ๋Œ์•„์™€์„œ User๋ฅผ ์ •์˜ํ•ด ์ค๋‹ˆ๋‹ค.

 

const db = require("../models");

const User = db.users;

 

Create

 

const addUser = async (req, res) => {
  let info = {
    username: req.body.username,
    password: req.body.password,
  };

  const user = await User.create(info).catch((err) => console.log(err));
  res.status(200).send(user);
};

 

Read

 

const getAllUsers = async (req, res) => {
  let users = await User.findAll({}).catch((err) => console.log(err));
  res.status(200).send(users);
};

const getUser = async (req, res) => {
  let id = req.params.id;
  let user = await User.findOne({ where: { id: id } }).catch((err) =>
    console.log(err)
  );
  res.status(200).send(user);
};

 

Update

 

const updateUser = async (req, res) => {
  let id = req.params.id;
  const user = await User.update(req.body, { where: { id: id } }).catch((err) =>
    console.log(err)
  );
  res.status(200).send(user);
};

 

Delete

 

const deleteUser = async (req, res) => {
  let id = req.params.id;
  await User.destroy({ where: { id: id } }).catch((err) => console.log(err));
  res.status(200).send("User is deleted");
};

 

์œ„ ํ•จ์ˆ˜๋“ค์„ exports ํ•ด์ค๋‹ˆ๋‹ค.

 

module.exports = {
  addUser,
  getAllUsers,
  getUser,
  updateUser,
  deleteUser,
};

Create a router

 

UserRouter.js ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ 

 

๊ฐ ๊ธฐ๋Šฅ๋ณ„๋กœ ๋ผ์šฐํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

 

const userController = require("../controllers/userController.js");

const router = require("express").Router();

router.post("/addUser", userController.addUser);

router.get("/allUsers", userController.getAllUsers);

router.get("/:id", userController.getUser);

router.put("/:id", userController.updateUser);

router.delete("/:id", userController.deleteUser);

module.exports = router;

 

Set a UserRouter

 

๋‹ค์‹œ app.js๋กœ ๋Œ์•„๊ฐ€์„œ ์•„๋ž˜ ๋ถ€๋ถ„์„

 

require("./models/index.js");

 

๋ผ์šฐํ„ฐ๋กœ ๋Œ€์ฒดํ•ด ์ค๋‹ˆ๋‹ค.

 

const router = require("./routers/UserRouter.js");
app.use("/api", router);

 

๊ทธ ๋‹ค์Œ ๋‹ค์‹œ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰์‹œ์ผœ ์ค๋‹ˆ๋‹ค.

 

node app.js

Test

 

Postman์„ ์ด์šฉํ•˜์—ฌ api๋ฅผ ํ…Œ์ŠคํŠธ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

Postman API Platform | Sign Up for Free

Postman is an API platform for building and using APIs. Postman simplifies each step of the API lifecycle and streamlines collaboration so you can create better APIs—faster.

www.postman.com

 

POST(Create)

 

addUser์— username๊ณผ password๋ฅผ json ํ˜•์‹์œผ๋กœ ์ž‘์„ฑํ•ด post ์š”์ฒญ์„ ๋ณด๋‚ด ์œ ์ €๋ฅผ ์ƒ์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

//POST
http://localhost:3000/api/addUser

 

GET(Read)

 

์œ„์—์„œ ์ƒ์„ฑํ•œ ์œ ์ €๊ฐ€ ์ œ๋Œ€๋กœ ๋“ค์–ด๊ฐ”๋Š”์ง€ allUsers๋กœ get ์š”์ฒญ์„ ๋ณด๋‚ด ์œ ์ € ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‘ ๋ฐ›์•„์™€ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

//GET
http://localhost:3000/api/allUsers

 

์•„๋ž˜์™€ ๊ฐ™์ด ์ •์ƒ์ ์œผ๋กœ ์ถ”๊ฐ€ํ•œ ์œ ์ €๊ฐ€ ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

PUT(Update)

 

id๊ฐ€ 1์ธ ์œ ์ €์˜ username์„ kalid๋กœ ๋ณ€๊ฒฝํ•ด PUT์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

//PUT
http://localhost:3000/api/1

 

 

GET

 

id๊ฐ€ 1์ธ ์œ ์ €์˜ ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜ค๋ฉด username์ด kalid๋กœ ๋ฐ”๋€Œ์–ด ์žˆ๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

//GET
http://localhost:3000/api/1

 

DELETE

 

id๊ฐ€ 1์ธ ์œ ์ €๋ฅผ Delete ํ•ด์ค๋‹ˆ๋‹ค.

 

//DELETE
http://localhost:3000/api/1

๋งˆ์ง€๋ง‰์œผ๋กœ ๋ชจ๋“  ์œ ์ €๋ฅผ ๋ณด๋ฉด ์‚ญ์ œ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 


Reference

 

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€