간단하게 TypeScript + React + Webpack 구성하기
Sequelize #2 쿼리, 외래키 (for MySQL)
2020-01-01
Explanation
두둥! 드디어 2020년 새해가 밝았습니다.
오늘은 새해 첫 날인 1월 1일! 원래는 어제 저녁에 여자친구와 해돋이를 보러 동해로 갈 계획이었지만.
여자친구가 없는 관계로, 이렇게 행복하게 집에서 포스팅을 하고 있습니다. (주륵..)
오늘은 Sequelize ORM을 사용한 Insert, Update 쿼리문과 외래키에 대해 알아보려 합니다~
역시 사용한 예제 코드는 아래의 깃허브에서 확인하실 수 있습니다.
https://github.com/falsy/blog-post-example/tree/master/sequelize-quick-start-2
이번 글은 지난 글의 내용을 전재로 이어서 진행됩니다.
https://falsy.me/sequelize-1-%ec%8b%9c%ec%9e%91%ed%95%98%ea%b8%b0-for-mysql/
아마도 제 생각에는 지난 글 정도의 내용만 이해하셨다면 충분히 공식 홈페이지의 메뉴얼을 검색해서 진행하실 수 있을 거 같지만, 그래도 이왕 쓰기 시작한 김에 조금 더 적어보려 해요.
지난 글에서는 GET 위주 였는데요. 이번엔 POST, PUT API를 만들어볼까요?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// /router/index.js const Router = require('koa-router'); const db = require('../db'); module.exports = () => { const router = new Router(); const models = db.models; ... router.post('/add', async (ctx) => { const { name, content } = ctx.request.body; await models.boards.create({ name, content }).catch(e => { console.log(e); }); ctx.status = 204; }); return router; }; |
‘koa-body’ 패키지가 설치되어 있습니다
위와 같이 POST 라우트를 추가하였어요. body에 name과 content를 받아서 boards 테이블에 insert한 답니다.
정상적으로 잘 동작하는지 테스트 해봐야겠죠?
원래는 포스트맨(https://www.getpostman.com/)을 주로 사용하지만… 그러면 또 스크린샷을 찍어야하는 번거러움이 있으므로 컬(curl)로 대신합니다.
터미널에서 아래와 같이 입력합니다~
1 |
$ curl -d '{"name":"falsy", "content":"hello world"}' -H "Accept: application/json" -H "Content-Type: application/json" http://localhost:7777/add |
컬(curl)에 대한 자세한 정보는 정광섭님의 글을 보면 좋아요!!
https://www.lesstif.com/pages/viewpage.action?pageId=14745703
우선 -d 옵션이 있으면 자동으로 POST로 설정이 되고 JSON 형태의 데이터를 보내고 Header에 ‘application/json’타입을 적어주고,
마지막으로는 만들었던 서버의 URI를 입력해주었었습니다.
그럼 이제 DB에 데이터가 잘 추가 되었는지 DB에 가서 확인을 해보면,
1 2 3 4 5 |
+----+-------+-------------+---------------------+ | id | name | content | created_at | +----+-------+-------------+---------------------+ | 1 | falsy | hello world | 2020-01-01 09:38:26 | +----+-------+-------------+---------------------+ |
짜잔!
멀티플 인설트 쿼리… 이게 맞는 영어 인지 모르겠습니다. 타이틀을 한글로 시작할 걸 그랬습니다…
여하튼 여러개의 데이터를 한번에 인설트하는 방법은 아래와 같습니다~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// /router/index.js const Router = require('koa-router'); const db = require('../db'); module.exports = () => { const router = new Router(); const models = db.models; ... router.post("/addList", async ctx => { await models.boards .bulkCreate([ { name: "blue", content: "hello" }, { name: "red", content: "world" } ]) .catch(e => { console.log(e); }); ctx.status = 204; }); return router; }; |
위와 같이 ‘bulkCreate’라는 메서드의 인자값을 배열로 하여 여러 로우 데이터를 추가하실 수 있답니다.
1 |
$ curl -X POST http://localhost:7777/addList |
1 2 3 4 5 6 7 |
+----+-------+-------------+---------------------+ | id | name | content | created_at | +----+-------+-------------+---------------------+ | 1 | falsy | hello world | 2020-01-01 09:38:26 | | 2 | blue | hello | 2020-01-01 10:01:20 | | 3 | red | world | 2020-01-01 10:01:20 | +----+-------+-------------+---------------------+ |
짜잔!
이제 마지막으로 업데이트는 아래와 같이 사용할 수 있답니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// /router/index.js const Router = require('koa-router'); const db = require('../db'); module.exports = () => { const router = new Router(); const models = db.models; ... router.put("/update", async ctx => { await models.boards .update( { content: "hi, world" }, { where: { name: "falsy" } } ) .catch(e => { console.log(e); }); ctx.status = 204; }); return router; }; |
대략 update 메서드를 사용하고, 첫번째 인자로 바꿀 내용에 관한 속성을, 그리고 두번째 인자로 대상에 대한 속성을 입력할 수 있답니다.
1 |
$ curl -X PUT http://localhost:7777/update |
1 2 3 4 5 6 7 |
+----+-------+-----------+---------------------+ | id | name | content | created_at | +----+-------+-----------+---------------------+ | 1 | falsy | hi, world | 2020-01-01 09:38:26 | | 2 | blue | hello | 2020-01-01 10:01:20 | | 3 | red | world | 2020-01-01 10:01:20 | +----+-------+-----------+---------------------+ |
짜잔!
외래키.
이름만 들어서는 아마도 외국에서 온 거 같습니다. 어려워 보입니다.
저도 잘 모릅니다.
대충, 두개의 테이블이 이어주는 거 같습니다.
대충, 조인문 쓰려면 필요한 줄 알았는데.
대충, 검색해보니 외래 키를 등록하지 않아도 조인 문을 쓸 수 있나봐요??
뭐든 괜찮아요. 전 조인문을 좋아하지 않으니까요.
일단 기존에 만들었던 ‘boards’ 테이블과 연결해서 사용할 ‘likes’ 라는 테이블을 만들어볼게요.
보니까 저번글에서 생략했던데..
이번엔 boards라는 모델값이 필요하니까 아래와 같이 만들었답니다.
1 2 3 4 5 6 7 8 9 10 11 12 |
const boardModel = require("./boards"); const likeModel = require("./likes"); module.exports = (Sequelize, sequelize) => { const boards = boardModel(Sequelize, sequelize); const likes = likeModel(Sequelize, sequelize, boards); return { boards, likes }; }; |
그리고 모델은 아래와 같이 만들었어요.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// /model/likes.js module.exports = (Sequelize, sequelize, boardModel) => { const likes = sequelize.define("likes", { id: { type: Sequelize.INTEGER(11).UNSIGNED, primaryKey: true, autoIncrement: true, allowNull: false }, board_id: { type: Sequelize.INTEGER(11).UNSIGNED, references: { model: boardModel, key: "id" }, allowNull: false }, count: { type: Sequelize.INTEGER(11).UNSIGNED, allowNull: false }, created_at: { type: Sequelize.DATE, defaultValue: Sequelize.fn("now"), allowNull: false } }); likes.sync(); return likes; }; |
딱 보면,
‘board_id’라는 컬럼이 boards의 id값과 연결 된 포링키가 된거쥬!
1 2 |
// likes 테이블이 만들어지는 쿼리문 CREATE TABLE IF NOT EXISTS `likes` (`id` INTEGER(11) UNSIGNED NOT NULL auto_increment , `board_id` INTEGER(11) UNSIGNED NOT NULL, `count` INTEGER(11) UNSIGNED NOT NULL, `created_at` DATETIME NOT NULL DEFAULT now(), PRIMARY KEY (`id`), FOREIGN KEY (`board_id`) REFERENCES `boards` (`id`)) ENGINE=InnoDB; |