지난 시간 장바구니 API를 추가했어요. 이번 시간에는 주문 API의 결제하기(주문하기)를 어떻게 처리해야 할지 고민해 보고 코드로 직접 구현해 볼게요.
먼저 LAST_INSERT_ID() 는 이름 그대로 마지막으로 insert한 id를 불러오는 함수에요.
SELECT LAST_INSERT_ID();
하지만 이 함수를 사용할 때는 몇 가지 주의할 점(단점)이 존재해요.
1. 여러 번 insert한 결과와 bulk insert한 결과가 다르게 나와요.
2. 서버 연결 후 별도의 insert가 없었다면 0이 나와요.
3. 가장 마지막에 insert한 테이블의 auto_increment 된 값을 불러와요.
MAX() 와 MIN() 은 자주 볼 수 있는 직관적인 함수로, 각각 가장 큰 값과 가장 작은 값을 반환해요.
SELECT MAX(칼럼명) FROM table;
SELECT MIN(칼럼명) FROM table;
주문하기 요청은 지금까지 만들었던 API들과 다르게 여러 테이블에 걸쳐 복합적으로 요청을 처리해야 해요.
delivery → orders → orderedBookorders 에는 delivery 의 id가 필요하고, orderedBook 에는 orders의 id가 필요하기 때문이에요. 의존성에 맞게 순서대로 들어가야 해요.오늘 작업한 OrdersController.js 의 코드를 살펴볼게요.
import conn from '../db.js';
import statusCode from 'http-status-codes';
// 주문 하기
export const order = (req, res) => {
const { items, delivery, totalQuantity, totalPrice, userId, firstBookTitle } = req.body;
let delivery_id = 3;
let order_id = 2;
// 1. 배송 정보 INSERT
let sql = `INSERT INTO delivery (address, receiver, contact) VALUES (?, ?, ?)`;
let values = [delivery.address, delivery.receiver, delivery.contact];
conn.query(sql, values, (err, results) => {
if (err) return res.status(statusCode.INTERNAL_SERVER_ERROR).json({message: err.message});
delivery_id = results.insertId;
});
// 2. 주문 정보 INSERT (위에서 받아온 delivery_id 사용)
sql = `INSERT INTO orders (book_title, total_quantity, total_price, user_id, delivery_id)
VALUES (?, ?, ?, ?, ?);`;
values = [firstBookTitle, totalQuantity, totalPrice, userId, delivery_id];
conn.query(sql, values, (err, results) => {
if (err) return res.status(statusCode.INTERNAL_SERVER_ERROR).json({message: err.message});
order_id = results.insertId;
});
// 3. 주문 상세 목록(orderedBook) 다중 INSERT
sql = `INSERT INTO orderedBook (order_id, book_id, quantity) VALUES ?`;
values = [];
items.forEach((item) =>
values.push([order_id, item.book_id, item.quantity])
);
conn.query(sql,[values], (err, results) => {
if (err) return res.status(statusCode.INTERNAL_SERVER_ERROR).json({message: err.message});
return res.status(statusCode.CREATED).json(results);
});
};
위 코드를 보면 세 번째 orderedBook 에 값을 넣을 때, 기존 단일 값만 들어갔던 values 에 배열을 통째로 넣어서 사용하는 것을 볼 수 있어요.
이때 주의할 점은 쿼리에 넘겨줄 때 values를 []로 한 번 더 감싸서 [values] 형태로 넣어줘야 동작한다는 것이에요
INSERT문을 작성할 때 칼럼이 많아질수록 배열의 순서를 매핑하는 과정이 점점 복잡해져요.
이때 INSERT INTO 테이블 SET ? 구문을 활용하면 객체를 이용해 값을 편하게 입력할 수 있어요.
// 기존 사용 방법
sql = `INSERT INTO orders (delivery_id, book_title, total_price, total_quantity, user_id) VALUES (?)`;
values =[deliveryId, firstBookTitle, totalPrice, totalQuantity, userId];
// 새로운 사용 방법
sql = `INSERT INTO orders SET ?`;
values = {
delivery_id: deliveryId,
book_title: firstBookTitle,
total_price: totalPrice,
total_quantity: totalQuantity,
user_id: userId,
};
오늘 생성한 ERD에요
