2024년 10월 8일
// likes.js
const express = require("express");
const router = express.Router();
router.use(express.json());
const { addLike, removeLike } = require("../controller/LikeController");
// 좋아요 추가
router.post("/:id", addLike);
// 좋아요 삭제
router.delete("/:id", removeLike);
module.exports = router;
// LikeController.js
const conn = require("../mariadb"); // db 모듈
const { StatusCodes } = require("http-status-codes"); // status code 모듈
const addlike = (req, res) => {
res.json("좋아요 추가");
};
const removeLike = (req, res) => {
res.json("좋아요 삭제");
};
module.exports = { addlike, removeLike };
워크벤치로 쿼리문이 맞는지 일단 확인해보자
이제 구현해보자
// LikeController.js
const conn = require("../mariadb"); // db 모듈
const { StatusCodes } = require("http-status-codes"); // status code 모듈
const addlike = (req, res) => {
const {liked_book_id} = req.params;
const {user_id} = req.body; // 지금은 토큰이 없으므로 Body값으로 확인해보자
let sql = "INSERT INTO likes (user_id, liked_book_id) VALUES(?, ?)";
let values = [user_id, liked_book_id];
conn.query(sql, values, (err, results) => {
if (err) {
console.log(err);
return res.status(StatusCodes.BAD_REQUEST).end();
}
return res.status(StatusCodes.OK).json(results);
});
};
POSTMAN) POST + localhost:9999/likes/2 + {”user_id” : 1}
400 에러코드 화면을 보고 에러를 확인해보면,
iked_book_id가 null값이 들어온다는 얘기 → liked_boo_id가 parameter로 들어올 때, liked_book_id가 아니라 id로 들어오기 때문
// LikeController.js
const conn = require("../mariadb"); // db 모듈
const { StatusCodes } = require("http-status-codes"); // status code 모듈
const addlike = (req, res) => {
const {id} = req.params;
const {user_id} = req.body; // 지금은 토큰이 없으므로 Body값으로 확인해보자
let sql = "INSERT INTO likes (user_id, liked_book_id) VALUES(?, ?)";
let values = [user_id, id];
conn.query(sql, values, (err, results) => {
if (err) {
console.log(err);
return res.status(StatusCodes.BAD_REQUEST).end();
}
return res.status(StatusCodes.OK).json(results);
});
};
POSTMAN) POST + localhost:9999/likes/2 + {”user_id” : 1}
POSTMAN) POST + localhost:9999/likes/3 + {”user_id” : 1}
// LikeController.js
const conn = require("../mariadb"); // db 모듈
const { StatusCodes } = require("http-status-codes"); // status code 모듈
const removeLike = (req, res) => {
const { id } = req.params; // book_id
const { user_id } = req.body;
let sql = "DELETE FROM likes WHERE user_id = ? AND liked_book_id = ?";
let values = [user_id, id];
conn.query(sql, values, (err, results) => {
if (err) {
console.log(err);
return res.status(StatusCodes.BAD_REQUEST).end();
}
return res.status(StatusCodes.OK).json(results);
});
};
POSTMAN) DELETE + localhost:9999/likes/2 + {”user_id” : 1 }
books테이블에 likes 개수가 몇 개인지 넣어야함
각 도서의 likes 개수를 likes테이블에서 liked_book_id에 해당하는 행의 개수를 세면 되니깐 likes 테이블을 이용해도 되지만,
개별 도서 조회 설계 단계에서 book의 정보에 ‘likes: 좋아요수, liked: boolean’을 넣어주기로 했으므로 새로운 쿼리를 넣어 요청할 예정
각 도서가 좋아요를 몇 개 받았는지 알아보자
count()를 사용할 예정
*워크벤치에서 read only 되는 경우 : PK가 없으면 read only 상태로 모드가 자동으로 묶여 나옴
일단 수동으로 INSERT 해보자
위의 쿼리문의 결과값을 books 테이블에 뿌려주기만 할 것임
SELECT *, (SELECT count(*) FROM likes WHERE liked_book_id=1) AS likes FROM books
id가 1인 책의 좋아요 개수를 선택해서 book테이블의 likes 컬럼에 추가한다
그런데 우리는, book id마다 좋아요 개수가 다른 데이터를 보여준다. 어떻게 해야할까?
위에서는 id=1인 책의 좋아요 개수를 모든 행에서 보여줬다. 그런데 우리는 books 테이블의 모든 행마다 id가 있으므로, books의 id가 liked_book_id와 일치하는 애들의 개수를 각각 보여주면 됨
SELECT , (SELECT count() FROM likes WHERE liked_book_id=books.id) AS likes FROM books
// BookController.js
const conn = require("../mariadb"); // db 모듈
const { StatusCodes } = require("http-status-codes"); // status code 모듈
// (카테고리별, 신간 여부) 전체 도서 목록 조회
const allBooks = (req, res) => {
let { category_id, news, limit, currentPage } = req.query;
let offset = limit * (currentPage - 1);
let sql =
"SELECT *, (SELECT count(*) FROM likes WHERE liked_book_id=books.id) AS likes FROM books";
let values = [];
if (category_id && news) {
... 생략 ...
POSTMAN) GET + localhost:9999/books?limit=4¤tPage=1&category_id=0
SELECT * FROM likes WHERE user_id=1 AND liked_book_id=2;
likes 테이블에서 user id가 1이고, book id가 2인 애를 선택하면 그 애만 나옴
그런데 행이 필요한게 아니라 개수가 필요함
SELECT count(*) FROM likes WHERE user_id = 1 AND liked_book_id = 2;
그런데 어차피 갯수는 1 아니면 0 이므로 존재하는지만 물어보면 됨
SELECT EXISTS (SELECT * FROM likes WHERE user_id = 1 AND liked_book_id = 2); -> 불리언 True값 : 1
SELECT EXISTS (SELECT * FROM likes WHERE user_id = 1 AND liked_book_id = 9); -> 불리언 Fals값 : 0
이제 구현해보자
먼저, 좋아요 했는지에 대한 여부의 쿼리문을 생각해 보면
SELECT ,
(SELECT EXISTS (SELECT FROM likes WHERE user_id = 1 AND liked_book_id = 2)) AS liked
FROM books WHERE books.id = 2;
좋아요 갯수까지 넣어서 생각해보면
SELECT ,
(SELECT count() FROM likes WHERE liked_book_id=books.id) AS likes,
(SELECT EXISTS (SELECT * FROM likes WHERE user_id = 1 AND liked_book_id = 8)) AS liked
FROM books WHERE books.id = 8;
원래 있던 쿼리문에 적용해서 구현해보자
// BookController.js
const conn = require("../mariadb"); // db 모듈
const { StatusCodes } = require("http-status-codes"); // status code 모듈
const bookDetail = (req, res) => {
let { user_id } = req.body;
let book_id = req.params.id;
let sql = `SELECT *,
(SELECT count(*) FROM likes WHERE liked_book_id=books.id) AS likes,
(SELECT EXISTS (SELECT * FROM likes WHERE user_id = ? AND liked_book_id = ?)) AS liked
FROM books
LEFT JOIN category
ON books.category_id = category.id
WHERE books.id = ?;`;
let values = [user_id, book_id, book_id];
conn.query(sql, values, (err, results) => {
if (err) {
console.log(err);
return res.status(StatusCodes.BAD_REQUEST).end();
}
if (results[0]) {
return res.status(StatusCodes.OK).json(results[0]); // 책 한 권만 보여주기
} else {
return res.status(StatusCodes.NOT_FOUND).end();
}
});
};
module.exports = { allBooks, bookDetail };
POSTMAN) GET + localhost:9999/books/2 + {”user_id” : 1}
POSTMAN) GET + localhost:9999/books/2 + {”user_id” : 4}
좋아요 갯수와 좋아요 불리언을 알 수 있음
POSTMAN) GET + localhost:9999/books/1 + {”user_id” : 1}
그런데 book의 id값이 이상하게 나옴 → book의 id값은 1부터 시작인데 0으로 출력된것을 볼 수 있음
컬럼명을 그냥 간단히 바꿔보자
// BookContoller.js
... 생략 ...
const bookDetail = (req, res) => {
let { user_id } = req.body;
let book_id = req.params.id;
let sql = `SELECT *,
(SELECT count(*) FROM likes WHERE liked_book_id=books.id) AS likes,
(SELECT EXISTS (SELECT * FROM likes WHERE user_id = ? AND liked_book_id = ?)) AS liked
FROM books
LEFT JOIN category
ON books.category_id = category.category_id
WHERE books.id = ?;`;
POSTMAN) GET + localhost:9999/books/1 + {”user_id” : 1}
id가 1로 이제 잘 들어가는 것을 볼 수 있다
🍎🍏 오늘의 느낀점 : 오늘은 서브쿼리, count(), exist(), 등을 배운 날이었다. 쿼리문으로 테이블을 손보지 않고 손쉽게 원하는 데이터만 뾱뾱 뽑아쓰니깐 뭔가 신기하고 명쾌한 느낌이 들었다. 쿼리문에 대해서도 많이 알고 있으면, 데이터를 쉽게 뽑아 쓸 수 있으니깐 잘 알고 있어야 겠다는 생각이 들었다.