[SeSAC X 코딩온] 웹개발자 풀스택 과정 8주차 회고 (2) | MVC_MySQL 연결 실습, 환경 변수, sequelize

옹잉·2024년 2월 19일
0

💡 2/16 MVC_MySQL 연결 실습, 환경 변수, sequelize


📍 MVC_MySQL 연결 실습 (회원가입, 로그인 기능 DB 연결하기)

회원가입 성공 시 login 페이지로 redirection 하기 위해 처리를 프론트 단에서 할 때,
document.location.href="(이동할 페이지 url)" 사용

ex. [ singup.ejs 파일 ]

<script>
      // POST /user/signup
      function register() {
        axios({
          ...
          },
        }).then((res) => {
          alert("회원가입 완료! 환영합니다😊");
          // 회원가입 성공 시, 로그인 페이지로 redirection
          document.location.href = "/user/signin";
        });
      }
    </script>

📍 환경 변수

Github에 프로젝트 push할 때, 올리고 싶지 않은 정보들을 관리하기 위해 사용한다.
예를 들어, MySQL 비밀번호 같은 중요한 정보들을 .env 파일에 작성한다.

사용 방법

  • 먼저 npm i dotenv로 dotenv를 설치 한 후 .env 파일 생성한다!
  • .env는 KEY=value로 작성하면 되는데, KEY는 항상 대문자로 작성한다.
  • node.js는 process.env 객체를 통해 환경 변수에 접근 할 수 있다.
  • .gitignore 파일에 .env 추가해서 github에 올라가지 않도록 한다.

만약 프로젝트 규모가 커지면 개발자 모드와 배포 모드의 .env가 생길텐데
이때는 npm i cross-env를 사용한다. (설치 시 불상사 방지를 위해 모듈 이름 꼭!! 정확히 쓰기)

[ .env 파일 예시]

MYSQL_PASSWORD=0000
API_KEY=adskf13adsf4a5sf354f
PORT=8080

(PORT는 굳이 .env에서 관리하지 않아도 상관없음!)


// [ app.js (서버 파일) ]

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

// console.log(process.env); // 내 컴퓨터에서 사용하는 모든 환경변수 조회

// .env에서 만들어둔 환경 변수를 읽어오기 위한 설정
const dotenv = require("dotenv").config();
const PORT = process.env.PORT; // process.env. 를 사용하기 위해서는 require("dotenv") 아래쪽에 위치해야한다.

app.get("/", (req, res) => {
  console.log("mysql pw: ", process.env.MYSQL_PASSWORD);
  console.log("API KEY: ", process.env.API_KEY);
  console.log("PORT: ", process.env.PORT);
  res.send("응답완료");
});

app.listen(PORT, () => {
  console.log(`http://localhost:${PORT}`);
});

REST Client

VS Code의 확장 프로그램으로 Postman을 사용하지 않고 VS Code 내부에서 API 테스트를 할 수 있는 기능을 제공한다.

// api.http 파일

### rest client
@server=http://localhost:8080 

GET {{server}}/

  • 변수
    선언 시 @변수명=초기값, 사용할 때는 {{변수명}}
  • 주석
    ### 샵 3개 작성해야함. 안그러면 Send Request 할 수 없음
  • 요청 작성 방법
    [HTTP 메서드] {{server(변수명)}}/ <- HTTP 메서드 뒤에는 URL 작성하는 것 처럼 붙여서 작성
    ex)
    @server=http://localhost:8080
    GET {{server}}/user

📍 sequelize

node.js 사용 시 DB와 연결하여 사용할 때, JS구문을 SQL로 변환해주는 ORM 라이브러리

ORM이란, Object Relational Mapping(관계 객체 매핑)의 약자로 객체와 DB 관계를 매핑(연결)하는 도구이다.

1. install

npm i sequelize sequelize-cli mysql2

  • sequelize : 시퀄라이즈 패키지
  • sequelize-cli : 시퀄라이즈 명령어 실행
  • mysql2 : mysql과 시퀄라이즈 연결하는 드라이버 (도구)

설치 후 npx sequelize init 을 하면 다음과 같이 config, migrations, models, seeders 폴더가 생성된다.

이 중 migration, seeders 폴더는 지워준다.

2. sequelize 생성 후 models > index.js 설정

models > index.js 파일에 아래와 같이 많은 코드가 있는데 최소한의 코드만 남기고 지워준다.

// 코드 정리 후


'use strict';

const Sequelize = require('sequelize');
const config = require(__dirname + '/../config/config.json')['development'];
const db = {};

// Sequelize 클래스를 이용해서 sequelize 인스턴스 생성
const sequelize = new Sequelize(config.database, config.username, config.password, config);

// 모델 모듈 불러와서 db 객체에 저장 (관계 형성 없을 경우)
db.sequelize = sequelize;
db.Sequelize = Sequelize;

db.Player = require("./Player")(sequelize, Sequelize);

module.exports = db;
관계 형성 관련 내용은 다음 포스팅에 할 예정!

// 코드 정리 전 (npx sequelize init 직후)

3. config > config.js 설정

// config.json

{
  "development": {
    "username": "name",
    "password": "0000",
    "database": "schema",
    "host": "127.0.0.1",
    "dialect": "mysql" // Sequelize는 다양한 RDBMS를 지원하는 ORM이기 때문에, 
					  // 명시적으로 나타내주는 것!
  <},
  "test": {},
  "production": {}
}

4. sequelize model 정의

models > index.js에서 생성한 sequelize 인스턴스를 전달받아
sequelize.define(params1, params2, params3)로 모델 정의한다.

  • params1 : 모델(테이블) 이름 설정
  • params2 : 컬럼 정의 => create 제약조건과 유사
  • params3 : 모델의 옵션 정의
const GameModel = function (sequelize, DataTypes) {
  const Game = sequelize.define(
    "Game",
    {
      game_id: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true,
        allowNull: false,
      },
      date: {
        type: DataTypes.DATE,
        allowNull: false,
      },
      location: {
        type: DataTypes.STRING(63),
        allowNull: false,
      },
    },
    {
      freezeTableName: true,
    }
  );
  return Game;
};

module.exports = GameModel;


5. app.js(서버 파일)에서 sequelize로 DB 연결

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

sequelize
  .sync({ force: false }) // 서버 실행될 때 마다 테이블 재생성 하는지 여부 (true: 재생성, false: 재생성 안함)
  .then(() => {
    console.log("DB 연결 성공!");
    app.listen(PORT, () => {
      console.log(`http://localhost:${PORT}`);
    });
  })
  .catch((err) => console.log(err));

6. CRUD

Sequelize 공식문서(model-querying-basics)

sequelize 쿼리문을 이용해 SQL문을 작성하지 않고 CRUD가 가능하다.
controller폴더에 작성한다. (sequelize 사용 안하면 model에서 .query메서드로 SQL문 작성함)

INSERT

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

// POST /user/signup
exports.post_signup = (req, res) => {
  // console.log(req.body); // {userid: , pw: , name: }
  models.User.create({
    userid: req.body.userid,
    pw: req.body.pw,
    name: req.body.name,
  }).then(() => {
    res.end();
  });
};

SELECT

전체 조회

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

// GET / players (전체 선수 목록 조회)
exports.getAllPlayer = async (req, res) => {
  try {
    const players = await models.findAll();
    console.log(players);
    res.send(players);
  } catch (err) {
    console.log("err", err);
    res.status(500).send("server error");
  }
};

특정 데이터 한 개 조회

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

// POST /user/signin
exports.post_signin = (req, res) => {
  models.User.findOne({
    // findOne은 객체 하나만 반환함! => result.length 사용할 수 없음 (findAll은 배열 반환)
    where: { userid: req.body.userid, pw: req.body.pw },
  }).then((result) => {
    console.log("Cuser findOne result: ", result); // {} or null
    if (result) res.send(true);
    else res.send(false);
  });
};

UPDATE

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

// POST /user/profile/edit
exports.edit_profile = (req, res) => {
  models.User.update(
    {
      name: req.body.name,
      pw: req.body.pw,
    },
    {
      where: { id: req.body.id },
    }
  ).then(() => {
    res.end();
  });
};

DELETE

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

// POST /user/profile/delete
exports.delete_profile = (req, res) => {
  models.User.destroy({
    where: { id: req.body.id },
  }).then(() => {
    res.end();
  });
};

Sequelize를 잘 사용한다면 정말 유용할 것 같다. 공식문서에 자세하게 설명이 되어있어서 참고하기도 좋은 것 같다!

profile
틀리더라도 🌸🌈🌷예쁘게 지적해주세요💕❣️

0개의 댓글