다음은 장바구니 조회관련 API를 작성하다 생긴 이슈이다.
const getCartItem = (req, res) => {
const {user_id, selected} = req.body;
let sql = `SELECT cartItems.id, book_id, title, summary, quantity, price, price*quantity as total_price
FROM cartItems
JOIN books ON(cartItems.book_id = books.id)
WHERE user_id = ? AND cartItems.id IN (?)`;
let values = [user_id, ...selected];
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);
})
}
보다시피 body로 2개를 받는데 유저의 아이디와 선택한 아이템들에 관한 아이디 값을 받는다.
헌데 문제는 이 selected는 배열이기에 SQL 쿼리를 작성하기 애매하다는 것에 있다.
즉, 값이 몇 개가 올 지 모른다는 것이다. 일단 배열을 스프레드 연산자(Spread Operator)로 풀어서 넣는다면 ?(플레이스홀더)는 현재 하나이기에 값이 하나만 들어가는 결과가 발생한다.

?(플레이스홀더) 하나에 어떻게 배열의 모든 값들을 대입할까?
자동 : 그냥 배열을 넣으면 된다.
mysql2 라이브러리는 플레이스홀더를 사용하여 배열의 값을 자동으로 처리할 수 있다. 때문에 배열의 길이에 따라 플레이스홀더가 자동으로 설정된다.
수동 : 플레이스홀더를 수동으로 설정
아래와 같이 배열의 값에 따라서 플레이스홀더 개수를 설정하는 방법이 있겠다.
let placeholders = selected.map(() => '?').join(',');
// 쿼리 작성
let sql = `SELECT cartItems.id, book_id, title, summary, quantity, price, price*quantity as total_price
FROM cartItems
JOIN books ON(cartItems.book_id = books.id)
WHERE user_id = ? AND cartItems.id IN (${placeholders})`;
// 배열의 값을 플레이스홀더로 전달
let values = [user_id, ...selected];
누가봐도 자동이 간편하다.
const getCartItem = (req, res) => {
const {user_id, selected} = req.body;
let sql = `SELECT cartItems.id, book_id, title, summary, quantity, price, price*quantity as total_price
FROM cartItems
JOIN books ON(cartItems.book_id = books.id)
WHERE user_id = ? AND cartItems.id IN (?)`;
let values = [user_id, selected];
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);
})
}
무사히 2개가 출력되는 모습!
