category 테이블의 id 와 books 의 category_id 를 fk로 연결하고 db 다이어그램에도 추가했어요.


join을 통해 books를 조회할 때 카테고리 이름도 보이게 되었어요.

export const findBookById = (req, res) => {
const { id } = req.params;
const sql = 'SELECT * FROM books LEFT JOIN category ON books.category_id = category.id WHERE books.id = ?';
db.query(sql, id, (err, results) => {
if (err) return res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({message: err.message});
if (results.length === 0) return res.status(StatusCodes.NOT_FOUND).end();
return res.status(StatusCodes.OK).json(results[0]);
});
};

DATE_ADD(), DATE_SUB() 함수를 사용하여 시간을 원하는 간격에 따라 더하고 빼서 구할 수 있어요.
SELECT DATE_ADD(기준이 되는 시간, 원하는 시간 간격);
SELECT DATE_SUB(기준이 되는 시간, 원하는 시간 간격);
// 2024.05.24 기준
SELECT DATE_ADD(NOW(), INTERVAL 1 DAY); // 2024.05.25 출력
SELECT DATE_SUB(NOW(), INTERVAL 1 DAY); // 2024.05.23 출력
between 문법을 통해 한 달 이내인 목록만 조회할 수 있어요.
const { categoryId, isNew } = req.query; 로 쿼리 스트링을 바꿨는데, new는 예약어니 바꿔야했는데, 신간인지는 boolean 타입이니까 is를 붙이는 게 맞다고 생각했어요.
export const findBooks = (req, res) => {
const { categoryId, isNew } = req.query;
let sql = 'SELECT * FROM books';
let values = [];
if (categoryId && isNew) {
sql += ' WHERE category_id = ? AND pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()';
values.push(categoryId);
}
else if (categoryId) {
sql += ' WHERE category_id = ?';
values.push(categoryId);
}
else if (isNew) {
sql += ' WHERE pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()';
}
db.query(sql, values, (err, results) => {
if (err) return res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({message: err.message});
return res.status(StatusCodes.OK).json(results);
});
};

이렇게 한 달 내의 책을 조회하도록 구현했어요.
SQL에서 offset 과 limit 을 사용하면 페이지네이션을 구현할 수 있어요.
쿼리스트링에서 limit 과 currentPage 를 받아 다음과 같이 작성했어요.
export const findBooks = (req, res) => {
const { categoryId, isNew, limit, currentPage } = req.query;
let sql = 'SELECT * FROM books';
const offset = limit * (currentPage - 1);
let values = [];
if (categoryId && isNew) {
sql += ' WHERE category_id = ? AND pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()';
values.push(categoryId);
}
else if (categoryId) {
sql += ' WHERE category_id = ?';
values.push(categoryId);
}
else if (isNew) {
sql += ' WHERE pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()';
}
sql += ' LIMIT ? OFFSET ?';
values.push(parseInt(limit || 3), offset);
db.query(sql, values, (err, results) => {
if (err) return res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({message: err.message});
return res.status(StatusCodes.OK).json(results);
});
};
