본문 바로가기
학원에서 배운 것/DBMS MongoDB

KDT 5th 웹개발자 입문 수업 34일차 - 1

by 쿠리의일상 2023. 3. 23.

Mongoose

npm i mongoose 로 설치

 

1. 모듈 가져오기

const mongoose = require('mongoose');

2. 몽고DB와 몽구스를 연결

const mongoose = require('mongoose');

const { MDB_URI } = process.env;
const connect = async () => {
  try {
    await mongoose.connect(MDB_URI, {
      dbName: 'kdt5',
      useNewUrlParser: true,
    });
    console.log('mongoose connect');

    mongoose.connection.on('error', (err) => {
      console.error('mongoDB connection Error');
    });

    mongoose.connection.on('disconnected', () => {
      console.error('mongoDB disconnected, reconnecting...');
      connect();
    });
  } catch (err) {
  // node.js 자체 에러
    console.error(err);
  }
};

module.exports = connect;

첫번째 인자로는 몽고DB의 주소를

두번째 인자로는 옵션객체를 설정

 

 

몽구스를 사용하면 몽고db의 문서를 다루기 위해 SchemaModel을 정의할 수 있다.

 

Schema 

문서의 구조 정의

 

Model

실제 데이터 베이스에 저장되는 문서를 다루는 인터페이스

 

3.스키마 정의 + 모델 정의

const mongoose = require('mongoose'); // 몽구스 모듈

const { Schema } = mongoose; // 몽구스 모듈의 Schema 클래스

const userSchema = new Schema(
  {
    id: {
      type: String,
      required: true,
      unique: true,
    },
    password: {
      type: String,
      required: true,
    },
    createAt: {
      type: Date,
      default: Date.now,
    },
  },
  {
    collection: 'mongoose-user',
  }
);

module.exports = mongoose.model('User', userSchema);

생성자 함수를 사용하여 스키마와 모델 만들기 new Schema({ 키값 지정 객체 }, {컬렉션 지정 객체})

 

회원 스키마 정의하기

_id 는 알아서 생성되므로 정의할 필요가 없다.

id 는 타입이 String 이고 required 는 필수요소, unique 는 중복값이 들어올 수 없음을 지정해주는 설정값이다.

   --> 그러므로 기존에 회원가입에 작성해주었던 아이디 중복확인 로직이 생략 가능하다.

createAt 의 default를 생성 시간이 삽입되게 Date.now 로 설정

 

* 컬렉션 이름은 따로 정해주지 않으면 XXXSchema 의 XXX에 s 가 붙는 형태로 자동 생성 된다.

 

const mongoose = require('mongoose');

const productSchema = mongoose.Schema({
  name: { type: String, required: true },
  price: { type: Number, required: true }
});

const Product = mongoose.model('Product', productSchema);

mongoose.Schema({ 스키마 설정 객체 }) 를 사용하여 User 모델의 스키마를 정의하고 

mongoose.model('모델명', 스키마변수) 로 모델을 생성해준다.

 

 

4. 생성된 모델을 사용하여 CRUD 작업 수행

모델명.쿼리문({객체}) 형태로 사용

모두 promise 를 리턴하는 시간이 걸리는 작업들이므로 await 를 붙여줘야 함.

 

Create

new 모델명( { 정해준 키와 값을 만족하는 객체 } )

몽고DB의  insertOne() / insertMany() 대신, 모델명.create() 사용

Read

몽고DB의 findOne() / find() 와 동일, 모델명.findOne() / find()

Update

몽고DB의 updateOne() / updateMany() 와 동일, 모델명.updateOne({ 키1 객체 }, { 키2 객체 }) ...

Delete

몽고DB의 deleteOne() / deleteMany() 와 동일, 모델명.deleteOne({ 조건 })

// Create
const newProduct = new Product({
  name: 'Apple',
  price: 1000
});
newProduct.save();

// Read
const products = await Product.find();
console.log(products);

// Update
await Product.updateOne({ name: 'Apple' }, { price: 1200 });

// Delete
await Product.deleteOne({ name: 'Apple' });

 

기존 몽고DB를 몽구스로 변경한 유저 관련 기능

const mongooseConnect = require('./mongooseConnect');
const User = require('../models/user');

mongooseConnect();

const REGISTER_SUCCESS_MSG =
  '회원 가입 성공! <br/><br/> <a href="/login">로그인으로 이동</a>';
const REGISTER_DUPLICATED_MSG =
  '회원가입 실패, 동일한 아이디가 존재합니다. <br/><br/> <a href="/register">회원 가입으로 이동</a>';
const REGISTER_UNEXPECTED_MSG =
  '회원가입 실패, 알 수 없는 문제가 발생하였습니다. <br/><br/> <a href="/register">회원 가입으로 이동</a>';
const LOGIN_FAIL_MSG =
  '아이디 혹은 비밀번호가 다릅니다. <br/><br/> <a href="/login">로그인 페이지로 이동</a>';
const LOGIN_UNEXPECRED_MSG =
  '로그인 실패, 알 수 없는 문제가 발생하였습니다. <br/><br/> <a href="/login">로그인으로 이동</a>';
const LOGIN_NOT_REGISTERED_MSG =
  '로그인 실패, 해당 아이디를 가진 회원이 존재하지 않습니다. <br/><br/> <a href="/register">회원 가입으로 이동</a>';
const LOGIN_NOT_PASSWORD_MSG =
  '로그인 실패, 비밀번호가 일치하지 않습니다. <br/><br/> <a href="/register">회원 가입으로 이동</a>';

// 리팩토링 후
// 회원가입
const registerUser = async (req, res) => {
  try {
    await User.create(req.body);
    res.status(200).send(REGISTER_SUCCESS_MSG);
  } catch (err) {
    console.error(err);
    res.status(500).send(REGISTER_UNEXPECTED_MSG);
  }
};

// 로그인 기능 추가하기
const loginUser = async (req, res) => {
  try {
    const findUser = await User.findOne({ id: req.body.id });
    if (!findUser) return res.status(400).send(LOGIN_NOT_REGISTERED_MSG);

    if (findUser.password !== req.body.password)
      return res.status(400).send(LOGIN_NOT_PASSWORD_MSG);

    req.session.login = true;
    req.session.userId = req.body.id;
    res.cookie('user', req.body.id, {
      maxAge: 1000 * 5,
      httpOnly: true,
      signed: true,
    });

    res.status(200).redirect('/dbBoard');
  } catch (err) {
    console.error(err);
    res.status(500).send(LOGIN_UNEXPECRED_MSG);
  }
};

module.exports = { registerUser, loginUser };