๐Ÿ’ซ ์˜ค์•Œ์— ๊ณผ ์”จํ€„๋ผ์ด์ฆˆ ๐Ÿ’ซ

What is ORM?

: ORM์€ ํ”„๋กœ๊ทธ๋žจ ์ƒ์˜ ๊ฐ์ฒด์™€ DB์˜ ํ…Œ์ด๋ธ”(Relation)์ด ์ผ๋Œ€์ผ ๋Œ€์‘ํ•˜๋Š” ๊ด€๊ณ„๋ฅผ ๋งบ๋Š” ๊ฒƒ์„ ์˜๋งˆํ•œ๋‹ค! ORM์„ ์ด์šฉํ•˜๋ฉด query๊ฐ€ ์•„๋‹Œ ๋ฉ”์„œ๋“œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ์žฅ์ ์ด๋‹ค! (SQL๋ฌธ์„ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์†Œํ†ตํ•  ์ˆ˜ ์žˆ๋‹ค.)

์˜ˆ)
If I use MySQL: SELECT * FROM user;
If I use ORM: user.findAll();

But!

: ์ฟผ๋ฆฌ๊ฐ€ ๋ณต์žกํ•ด์ง€๋ฉด ORM์œผ๋กœ ํ‘œํ˜„ํ•˜๋Š” ๋ฐ ํ•œ๊ณ„๊ฐ€ ์ƒ๊ธด๋‹ค.
: raw query์— ๋น„ํ•ด ๋Š๋ฆฌ๋‹ค.

๋‹ค์–‘ํ•œ ORM ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์กด์žฌํ•œ๋‹ค.
์˜ˆ) Sequelize, Djanggo ORM, TypeORM, JPA/Hibernate ๋“ฑ

Sequelize

: Node.js์˜ ๋Œ€ํ‘œ์ ์ธ ORMํ”„๋ ˆ์ž„์›Œํฌ, Promise๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค.
: Sequelize-cli๋Š” sequelize๋ฅผ ์ข€ ๋” ํšจ์œจ์ ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ชจ๋“ˆ.

What can we do with Sequelize-cli

: Sequelize-cli๋Š” ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ํˆด์ด๋‹ค.
: ๋ชจ๋ธ์„ ์ƒ์„ฑํ•ด์ฃผ๊ฑฐ๋‚˜ ์Šคํ‚ค๋งˆ๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š”๋‹ค!

then what is "Migration"

: ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ ์Œ“์ธ ๋ฐ์ดํ„ฐ๋ฅผ ํ•„๋“œ๋กœ ์˜ฎ๊ฒจ์ฃผ๊ฑฐ๋‚˜, ์ •์˜๋ฅผ ๊ฐ–๊ณ  ์žˆ๋Š” ์ƒˆ๋กœ์šด ํ…Œ์ด๋ธ”์„ ๋งŒ๋“œ๋Š” ๊ฒƒ ์ž์ฒด์™€ ๊ทธ ๊ธฐ๋ก์„ ๋งํ•œ๋‹ค!

and... what is "Model"

: ํด๋ž˜์Šค๋ฅผ ๋ฉ”์†Œ๋“œ์™€ ์†์„ฑ์ด ํฌํ•จ๋œ ํ”„๋กœํ† ํƒ€์ž…์ด๋ผ๊ณ  ํ•œ๋‹ค๋ฉด, ๋ชจ๋ธ์€ ๋ฉ”์†Œ๋“œ์™€ ์†์„ฑ, ๊ทธ๋ฆฌ๊ณ  ๊ฑฐ๊ธฐ์— ์—”ํ‹ฐํ‹ฐ(์Šคํ‚ค๋งˆ)๊ฐ€ ํฌํ•จ๋œ ๊ฐœ๋…์ด๋ผ ํ•  ์ˆ˜ ์žˆ๋‹ค.
: ์•”ํŠผ ์ค‘์š”ํ•œ ๊ฒƒ์€ ๋ชจ๋ธ์—๋Š” ์—”ํ‹ฐํ‹ฐ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ์žˆ๋‹ค๋Š” ์ !

what's different between "Model" and "Migration"

Migration์€ ์Šคํ‚ค๋งˆ๋ฅผ ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค ๊ฒƒ์ธ์ง€ ์„ค์ •ํ•˜๋Š” ํŒŒ์ผ์ด๋‹ค.
Model์€ ํฌ๋ฆฌ์—์ดํŠธ, ์—…๋ฐ์ดํŠธ, ๋””์ŠคํŠธ๋กœ์ด ๋“ฑ์˜ ๋ฉ”์†Œ๋“œ, ์ฆ‰ ๋ชจ๋ธ์— ์žˆ๋Š” ๊ธฐ๋Šฅ๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

์Šคํ”„๋ฆฐํŠธ ์˜ˆ์‹œ์—์„œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ์— ๋””ํดํŠธ๊ฐ’์„ ์„ค์ •ํ•˜๋ฉด, ์•„์˜ˆ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์ž์ฒด?์— ํ…Œ์ด๋ธ”์„ ํ˜•์„ฑํ•  ๋•Œ ๋””ํดํŠธ๊ฐ’์ด ์ ์šฉ๋˜๋Š” ๊ฒƒ์ด๊ณ ,
๋ชจ๋ธ ํŒŒ์ผ์— ๋””ํดํŠธ๊ฐ’์„ ์„ค์ •ํ•˜๋ฉด, ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ์ฃผ๊ณ  ๋ฐ›์„ ๋•Œ ๋””ํดํŠธ๊ฐ’์ด ํ˜•์„ฑ๋˜๋Š” ๊ฒƒ์ด๋‹ค.
(๋ฌผ๋ก  ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๋‘ ๊ตฐ๋ฐ์— ๋™์ผํ•˜๊ฒŒ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•  ๋“ฏ ์‹ถ๋‹ค.)

sequlize-cli ๋ช…๋ น์–ด

ํ”„๋กœ์ ํŠธ ์‹œ์ž‘ํ•˜๊ธฐ!

npx sequelize-cli init
์ด ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๋Š”๋ฐ!
์ž…๋ ฅํ•˜๋ฉด ์ƒ๊ธฐ๋Š” ์—ฌ๋Ÿฌ ํด๋”๋“ค์ด ์žˆ๋‹ค!
๊ฐ๊ฐ์˜ ํดํ„ฐ๊ฐ€ ํ•˜๋Š” ์—ญํ• ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  • config: CLI๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์—ฐ๊ฒฐ๋˜๋Š”์ง€๋ฅผ ์„ค๋ช…ํ•˜๋Š” configํŒŒ์ผ์„ ํฌํ•จ
  • models: ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•œ ๋ชจ๋“  ๋ชจ๋ธํŒŒ์ผ์„ ํฌํ•จ
  • mogrations: ๋ชจ๋“  ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒŒ์ผ ํฌํ•จ
  • seeders: ๋ชจ๋“  ์‹œ๋“œํŒŒ์ผ ํฌํ•จ
    (seed๋Š” ์„œ๋ฒ„๊ฐ€ ์‹œ์ž‘๋  ๋•Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•  ์ •์ ์ธ ๋ฐ์ดํ„ฐ๋“ค์„ DB์— ์ถ”๊ฐ€ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ์˜๋ฏธํ•œ๋‹ค. ์ด๋ฒˆ ์Šคํ”„๋ฆฐํŠธ์—์„œ๋Š” ํ™œ์šฉ๋˜์ง€ ์•Š๋Š” ๋“ฏ ์‹ถ๋‹ค.)

Express ์‘๋‹ต๋ฉ”์†Œ๋“œ

Sequelize ๋ฌธ๋ฒ•

Simple INSERT queries: Model.create()

// Create a new user
const jane = await User.create({ firstName: "Jane", lastName: "Doe" });
console.log("Jane's auto-generated ID:", jane.id);

Simple SELECT queries: Model.findAll()

// Find all users
const users = await User.findAll();
console.log(users.every(user => user instanceof User)); // true
console.log("All users:", JSON.stringify(users, null, 2));

Applying WHERE clauses

Post.findAll({
  where: {
    authorId: 2
  }
});
// SELECT * FROM post WHERE authorId = 2

Simple UPDATE queries

// Change everyone without a last name to "Doe"
await User.update({ lastName: "Doe" }, {
  where: {
    lastName: null
  }
});

Simple DELETE queries: Model.destroy()

// Delete everyone named "Jane"
await User.destroy({
  where: {
    firstName: "Jane"
  }
});

Creating in bulk: Model.bulkCreate()

const captains = await Captain.bulkCreate([
  { name: 'Jack Sparrow' },
  { name: 'Davy Jones' }
]);
console.log(captains.length); // 2
console.log(captains[0] instanceof Captain); // true
console.log(captains[0].name); // 'Jack Sparrow'
console.log(captains[0].id); // 1 // (or another auto-generated value)

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ