장바구니에서 결제로 넘어간 후, order 테이블에 해당 유저의 정보를 INSERT한 뒤, order 테이블에 INSERT된 id 값을 알아낸 뒤, order_product 테이블에 해당 유저와 order.id와 상품의 정보를 입력하려고 하였다.
LAST_INSERT_ID()
이를 위해 처음에는 아래와 같이 LAST_INSERT_ID()
를 사용하였다. LAST_INSERT_ID()
는 최근 INSERT한 데이터의 id, 혹은 AUTO_INCREMENT에 따라 생성된 최근 id를 반환하는데, 이를 사용하는 것이 내가 원하는 구현 사항을 충족하는 것이라고 생각하였다.
await appDataSource.query(
`INSERT INTO
orders (user_id, order_status_id)
VALUES
(?, 1);
`, [userId]
);
const lastInsertOrderId = await appDataSource.query(
`SELECT LAST_INSERT_ID();`
);
return lastInsertOrderId[0]["LAST_INSERT_ID()"];
위의 스크린샷을 보면, 숫자를 뽑아내기 위해 변수명과 몇 번째 인덱스, 그리고 그 키의 이름을 적어 INSERT된 id를 찾을 수 있었다.
하지만... 역시나... 멘토 호준님께서 아래와 같이 코멘트를 달아주셨다.
이 힌트를 통하여 구글링을 하였으나, 처음에는 MyBatis를 사용하는 방법, 혹은 LAST_INSERT_ID()
를 사용하는 방법 외에는 별다른 소득이 없었고, 이렇게 해내지 못하는 걸까라는 생각을 하였다. 그러다가 호준님이 '실행하면 결과로 insertId를 받을 수 있으니'라고 쓰신 것에 집중하여 구글링의 방향을 바꾸어보았다.
W3schools의 Node.js MySQL Insert Into 페이지에서 내가 원하는 답을 찾을 수 있었다.
The Result Object
- When executing a query, a result object is returned.
- The result object contains information about how the query affected the table.
- The result object returned from the example above looks like this:
{ fieldCount: 0, affectedRows: 14, insertId: 0, serverStatus: 2, warningCount: 0, message: '\'Records:14 Duplicated: 0 Warnings: 0', protocol41: true, changedRows: 0 }
쿼리를 실행하게 될 때, 결과 객체가 반환되며, 결과 객체에는 쿼리가 테이블에 미치는 영향에 대한 정보가 포함되어 있다는 것을 알게 되었다.
그래서 나는 아래와 같이 나의 코드를 다시 작성해보았다.
const createOrder = await queryRunner.query(
`INSERT INTO
orders (user_id, order_status_id)
VALUES
(${userId}, ${OrderStatusId.ORDER_DONE});
`
);
const orderId = createOrder.insertId;
두 번의 쿼리(INSERT & SELECT)를 실행하여 INSERT된 PK id값을 받아왔던 첫 번째의 방법(LAST_INSERT_ID()
)과는 달리, 한 번의 쿼리로 INSERT한 후, 그 result objcet를 통해 insertId를 받아오는 두 번째 방법이 훨씬 경제적이고 가독성이 훨씬 높아졌다!
LAST_INSERT_ID() 를 쓰기 위해 굳이 쿼리문을 하나 더 넣었어야 했는데 이런 방법이 있었군요...! 😃 가은님도 호준님도 리스펙... 🌟 2차 플젝때 저도 이거 써볼래요! 🤩