궤도

[백엔드] Node.js + Sequelize + MySQL 내 책 리스트를 만들어보자 본문

💻 현생/📃 VIVA

[백엔드] Node.js + Sequelize + MySQL 내 책 리스트를 만들어보자

영이오 2021. 2. 9. 14:29

제목을 뭐라고 하면 좋을지 모르겠어서 저렇게 대충 썼다.

범용성이 떨어지는 제목이 됐으나, 이게 최선이었다. 아무튼 이 게시물에서는 내 책 리스트를 만들 것이다.

사용자가 보유한 책들을 일반교재/학원교재/오답노트로 나눠서 보여주고, 각 책들에 대한 삭제 기능과 오답노트에 대해서는 수정 기능도 넣어줄 것이다. 아 그리고 검색 기능에선 할 수 없던 오답노트 생성 기능도 넣을 것이다.

 

얘네들을 구현하면 된다는 것이다.


책 리스트 가져오기

 

사실 이건 이미 했었다.

myunji.tistory.com/151

 

[백엔드] Node.js + Sequelize + MySQL 메인 화면을 만들어보자

지난 시간에 회원가입과 로그인을 구현했다. 로그인을 했으면? 이제 메인 화면이 나와야 한다. 우리의 메인화면 프로토타입이다. 화면을 보면 내가 줘야 하는건 다음과 같다. 1. 유저의 '닉네임',

myunji.tistory.com

 

똑같은 기능을 하는 코드가 이미 있는데 또 만들 이유는 없으니까 app.js에 한줄만 추가해주자

 

app.js

app.use('/api/book-list', require("./routes/home"));

이렇게 하면 home에 있던 코드를 api/book-list 주소에서도 사용할 수 있다.

 

localhost:3001/api/home/workbook?stu_id=samdol

localhost:3001/api/book-list/workbook?stu_id=samdol

 

이 두 주소가 같은 결과를 보여줄 것이란 뜻이다.

 

localhost:3001/api/book-list/workbook?stu_id=samdol

사용자의 교재 리스트


책 삭제하기

 

프론트에서 삭제할 교재의 workbook_sn와 사용자의 stu_id를 넘겨주면 이를 기준으로 stu_workbook/incor_note 테이블에서 삭제 작업을 할 것이다. 일반 교재와 학원 교재는 모두 stu_workbook 테이블에 있고 오답노트만 incor_note 테이블에 있기 때문에 일반 교재와 학원 교재의 삭제 코드는 동일하고, 오답노트 삭제 코드만 다르다.

 

그럼 먼저 일반교재와 학원 교재를 삭제하는 코드부터 보도록 하자.

 

routes/book-list.js(일반, 학원 교재 삭제)

async function deleteBook(req, res) {
    const input_stu_id = req.query.stu_id;
    const sn = req.params.sn;

    let result = await models.student.findOne({
        where: {
            stu_id: input_stu_id
        }
    });

    models.stu_workbook.destroy({
        where: {
            stu_sn: result.dataValues.stu_sn,
            workbook_sn: sn
        }
    })
        .then(num => {
            if (num == 1) { //성공
                res.send({
                    message: "Delete book",
                    status: 'success'
                });
            } else { //데이터 입력 잘못한듯
                res.send({
                    message: "Data was not found!",
                    status: 'fail'
                });
            }
        })
        .catch(err => { //에러
            res.send({
                message: "Could not delete book",
                status: 'fail'
            });
        });
}

// Delete
//localhost:3001/api/book-list/workbook/'삭제할 workbook_sn'?stu_id=samdol
router.delete('/workbook/:sn', async function (req, res, next) {
    deleteBook(req, res);
});

// Delete
//localhost:3001/api/book-list/academy/'삭제할 workbook_sn'?stu_id=samdol
router.delete('/academy/:sn', async function (req, res, next) {
    deleteBook(req, res);
});

보면 알겠지만 deleteBook 함수만 살펴보면 된다.

 

    const input_stu_id = req.query.stu_id;
    const sn = req.params.sn;

    let result = await models.student.findOne({
        where: {
            stu_id: input_stu_id
        }
    });

늘 하던대로 입력받은 stu_id를 기준으로 사용자를 찾아내어 pk인 stu_sn을 뽑아낸다.

 

    models.stu_workbook.destroy({
        where: {
            stu_sn: result.dataValues.stu_sn,
            workbook_sn: sn
        }
    })
        .then(num => {
            if (num == 1) { //성공
                res.send({
                    message: "Delete book",
                    status: 'success'
                });
            } else { //데이터 입력 잘못한듯
                res.send({
                    message: "Data was not found!",
                    status: 'fail'
                });
            }
        })
        .catch(err => { //에러
            res.send({
                message: "Could not delete book",
                status: 'fail'
            });
        });

그리고 stu_sn과 프론트에서 넘어온 workbook_sn(sn)을 이용해 stu_workbook 테이블에서 교재를 삭제하면 된다.

 

routes/book-list.js(오답노트 삭제)

// Delete
//localhost:3001/api/book-list/incor-note/'삭제할 note_sn'?stu_id=samdol
router.delete('/incor-note/:sn', async function (req, res, next) {
    const input_stu_id = req.query.stu_id;
    const sn = req.params.sn;

    let result = await models.student.findOne({
        where: {
            stu_id: input_stu_id
        }
    });

    models.incor_note.destroy({
        where: {
            stu_sn: result.dataValues.stu_sn,
            note_sn: sn
        }
    })
        .then(num => {
            if (num == 1) { //성공
                res.send({
                    message: "Delete book",
                    status: 'success'
                });
            } else { //데이터 입력을 잘못한듯
                res.send({
                    message: "Data was not found!",
                    status: 'fail'
                });
            }
        })
        .catch(err => { //에러
            res.send({
                message: "Could not delete book",
                status: 'fail'
            });
        });
});

오답노트는 삭제의 대상이 incor_note 테이블에 있다는걸 제외하고는 동일하다. 그렇기 때문에 굳이 부연 설명을 하지 않겠다.

 

localhost:3001/api/book-list/workbook/7051?stu_id=samdol

교재 삭제 결과창


오답노트 정보 수정하기

 

우리 오답노트에는 수정 기능이 있다. 많이 수정할 수 있는건 아니고 그냥 제목과 표지 정도를 바꿀 수 있다. 해보자

 

routes/book-list.js(오답노트 수정)

// Update incor-note
//localhost:3001/api/book-list/incor-note/'수정할 note_sn'?stu_id=samdol
router.put('/incor-note/:sn', async function (req, res, next) {
    const input_stu_id = req.query.stu_id;
    const sn = req.params.sn;
    let body = req.body;

    let result = await models.student.findOne({
        where: {
            stu_id: input_stu_id
        }
    });

    models.incor_note.update({ //이름, 사진 수정
        note_name: body.note_name,
        note_photo: body.note_photo
    }, {
        where: { 
            stu_sn: result.dataValues.stu_sn,
            note_sn: sn
         }
    })
        .then(num => {
            if (num == 1) { //성공
                res.send({ 
                    message: "incor_note was updated successfully.",
                    status: 'success'
                });
            } else { //데이터 입력 잘못한듯
                res.send({
                    message: "Data was not found or req.body is empty!",
                    status: 'fail'
                });
            }
        })
        .catch(err => { //에러
            res.send({
                message: "Error updating incor_note",
                status: 'fail'
            });
            console.log(err);
        });
});

별거 없지만 설명을 해보자면

 

    const input_stu_id = req.query.stu_id;
    const sn = req.params.sn;
    let body = req.body;

    let result = await models.student.findOne({
        where: {
            stu_id: input_stu_id
        }
    });

늘 하는 stu_id를 stu_sn으로 바꿔주는 과정...

 

    models.incor_note.update({ //이름, 사진 수정
        note_name: body.note_name,
        note_photo: body.note_photo
    }, {
        where: { 
            stu_sn: result.dataValues.stu_sn,
            note_sn: sn
         }
    })

update...

 

        .then(num => {
            if (num == 1) { //성공
                res.send({ 
                    message: "incor_note was updated successfully.",
                    status: 'success'
                });
            } else { //데이터 입력 잘못한듯
                res.send({
                    message: "Data was not found or req.body is empty!",
                    status: 'fail'
                });
            }
        })
        .catch(err => { //에러
            res.send({
                message: "Error updating incor_note",
                status: 'fail'
            });
            console.log(err);
        });

결과 처리...

 

교재 수정 결과창


오답노트 생성하기

 

오답노트는 홈 화면에서 생성할 수도 있고, 교재 리스트에서 생성할 수도 있다. 그래서 home.js 파일에 만들기로 했다.

 

//localhost:3001/api/home/incor-note?stu_id=samdol
//localhost:3001/api/book-list/incor-note?stu_id=samdol
router.post('/incor-note', async function (req, res, next) {
    const input_stu_id = req.query.stu_id;
    let body = req.body;

    let result = await models.student.findOne({
        where: {
            stu_id: input_stu_id
        }
    });

    models.incor_note.create({ //이름, 사진, 학생 입력함. 생성 날짜는 자동으로 들어감
        stu_sn: result.dataValues.stu_sn,
        note_name: body.note_name,
        note_photo: body.note_photo
    })
    .then(result => {
        res.send({
          message: 'Inserted in DB',
          status:'success',
          data:{ //result는 그냥 내가 postman에서 보려고 넣은거라 실제로 쓸 때는 빼도 괜찮음.
              result
          }
        })
      })
      .catch(err => { //무슨 문제가 생겼을까...
        res.send({
          message:
            err.message || "Some error occurred while insert data.",
          status:'fail'
        });
      });
});

거의 update가 create로 바뀐 수준의 차이라 굳이 설명할 필요 없을 것 같다. 다만 오답노트 생성시에는 이 노트를 소유하고 있는 학생을 명시해야 하니 stu_sn을 받아야 한다.

 

localhost:3001/api/book-list/incor-note?stu_id=samdol

오답노트 생성 결과창

Comments