8-5 좋아요 API와 서브쿼리
LikeController.js에서 좋아요 추가, 취소(제거)기능을 구현 모듈화하여 likes.js에서 연결하였습니다.
likes.js
// likes.js
const express = require('express');
const router = express.Router();
const {addLike, removeLike} = require('../controller/LikeController'); // 컨트롤러js에서 기능 받아옴
router.use(express.json());
// 좋아요 추가
router.post('/:id', addLike);
// 좋아요 취소/삭제
router.delete('/:id', removeLike);
module.exports = router;
LikeController.js
const conn = require('../../../../mariadb'); // maria db
const { StatusCodes } = require('http-status-codes'); // http status
// 좋아요 추가
const addLike = (req, res) => {
const { id } = req.params;
const { user_id } = req.body; // jwt가 없어서 임시로 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);
})
};
// 좋아요 취소
const removeLike = (req, res) => {
const { id } = req.params;
const { user_id } = req.body; // jwt가 없어서 임시로 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);
})
};
module.exports = {
addLike,
removeLike
};
mariaDB로 MySQLworkbench로 연동하여, 책 목록을 불러오는 API기능 중 좋아요(likes 테이블을 참고/기준으로) 여부를 판단하여 출력합니다(좋아요 개수만).
BookController.js
const conn = require('../../../../mariadb');
const { StatusCodes } = require('http-status-codes'); // http status
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 books.id = liked_book_id) AS likes FROM books";
let values = [];
if (category_id && news) {
sql += " WHERE category_id=? AND pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()";
values = [category_id]
} else if (category_id) {
sql += " WHERE category_id=?";
values = [category_id]
} else if (news) {
sql += " WHERE pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()"
}
sql += " LIMIT ? OFFSET ?";
values.push(parseInt(limit), offset);
conn.query(sql, values,
(err, results) => {
if (err) {
console.log(err);
return res.status(StatusCodes.BAD_REQUEST).end();
}
if (results.length)
return res.status(StatusCodes.OK).json(results);
else
return res.status(StatusCodes.NOT_FOUND).end();
})
}
const bookDetail = (req, res) => {
let {user_id} = req.body;
let book_id = req.params.id;
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 = ?;`;
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,
}
서브 쿼리
count ()
AS
likes 테이블 중 1번 책을 좋아요를 한 행 조회
SELECT * FROM likes WHERE liked_book_id = 1;
likes 테이블 중 1번 책을 좋아요를 한 행의 개수
SELECT count(*) FROM likes WHERE liked_book_id;
books의 테이블 전체조회
SELECT * FROM books;
books의 테이블 전체조회
SELECT *, (값) AS (새로 추가할 컬럼명) FROM books; // 값에는 조건을 입력
ex) SELECT *, (SELECT count(*) FROM likes WHERE books.id = liked_book_id) AS likes FROM books;
SELECT count(*) FROM likes likes 테이블에서 개수를 셉니다.WHERE books.id = liked_book_id books 테이블의 id 값과 likes 테이블의 liked_book_id값이 일치하는 행의 수를 카운트합니다.likes
| user_id | liked_book_id |
|---|---|
| 1 | 1 |
| 2 | 2 |
| 3 | 1 |
book
| id | title |
|---|---|
| 1 | little book |
| 2 | big book |
| 3 | apple book |
===> 좋아요 수를 반영하여 출력됩니다.
| id | title | likes |
|---|---|---|
| 1 | little book | 2 |
| 2 | big book | 1 |
| 3 | apple book | 0 |
EXISTS를 사용하여 존재여부/= 사용자가 좋아요를 눌렀는지를 확인할 수 있습니다.
좋아요 여부
SELECT *,
(SELECT EXISTS (SELECT * FROM likes WHERE user_id = 1 AND liked_book_id = 1)) AS liked
FROM books WHERE books.id = 1;
개수도 포함해서
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 = 1)) AS liked
FROM books WHERE books.id = 8;
개별도서조회 sql join까지
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 = 1)) AS liked
FROM books
LEFT JOIN category
ON books.category_id = category.id
WHERE books.id = 1;
서브쿼리를 사용하여 간단하게?.. 조건들을 추가하여 특정 값을 조회, 계산, 조건제한 등 원하는 값을 조회할 수 있다는 것을 알 수 있었습니다.