Skip to content

๐Ÿ“– ORM ๊ธฐ์ˆ ์Šคํƒ ๋น„๊ต

baegyeong edited this page Nov 29, 2024 · 2 revisions

ORM ๊ธฐ์ˆ ์Šคํƒ ๋น„๊ต

๋ถ„์•ผ ์ž‘์„ฑ์ž ์ž‘์„ฑ์ผ
BE ๊น€๋ฏผ์ˆ˜ 24๋…„ 10์›” 28์ผ

Sequelize

  • ํ•œ ๋•Œ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋˜ node ์ง„์˜์˜ ORM ๊ธฐ์ˆ 
  • ์˜ค๋ž˜๋œ ๋งŒํผ ๊ฑฐ๋Œ€ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ˜•์„ฑ๊ณผ ๊ธฐ์ˆ ์  ์•ˆ์ •์„ฑ์ด ๋†’๋‹ค.

์ง€์› ๊ธฐ๋Šฅ

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ Model ๊ฐ์ฒด
  • ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ง€์›
  • ์ฟผ๋ฆฌ์— ๋”ฐ๋ฅธ ๊ธฐ๋ณธ ๋ฉ”์„œ๋“œ ์ง€์›
  • validator์™€ ์ œ์•ฝ์กฐ๊ฑด ์„ค์ • ๊ฐ€๋Šฅ
  • raw ์ฟผ๋ฆฌ ์ง€์›
  • ๋…ผ๋ฆฌ์  ์‚ญ์ œ ์ง€์›
  • Lazy Loading/Eager Loadingย ์ง€์›

๋‚ด๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ์žฅ์ 

  • ๊ณต์‹๋ฌธ์„œ - ์˜ค๋ž˜๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ๊ณต์‹๋ฌธ์„œ๊ฐ€ ์ž˜ ์ •๋ฆฌ๋˜์–ด์žˆ๋‹ค.

๋‚ด๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ๋‹จ์ 

  • ์ฝ”๋“œ ๊ฐ€๋…์„ฑ: ์‚ฌ์šฉํ•˜๊ธฐ์— ๊ฐ€์žฅ ํฐ ๋‹จ์ ์ด๋ผ๊ณ  ์ƒ๊ฐ, ๋ชจ๋ธ ์„ค์ • ์‹œ ์นผ๋Ÿผ์˜ ํƒ€์ž…์ด๋‚˜ ํŠน์ง•์„ ์ž‘์„ฑํ•˜๋Š” ์ฝ”๋“œ๋‚˜, ์—ฐ์‚ฐ ๊ด€๋ จ ๋ฉ”์„œ๋“œ์˜ ์ฝ”๋“œ๊ฐ€ ๋”๋Ÿฌ์šธ ์ˆ˜ ์žˆ๋‹ค.
  • ์ฟผ๋ฆฌ๊ฐ€ ๋Š๋ฆฌ๋‹ค: ๋ฉ”์„œ๋“œ์—์„œ ์ฟผ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ์— ๋‹ค๋ฅธ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.
  • ๋†’์€ ๋Ÿฌ๋‹์ปค๋ธŒ: ORM ๋ฉ”์„œ๋“œ๊ฐ€ sql๊ณผ ๊ฑฐ๋ฆฌ๊ฐ€ ๋ฉ€ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— sql์„ ์•ˆ๋‹ค๊ณ  ํ•ด๋„ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋‹ค.
  • ๋ณต์žกํ•œ ์ฝ”๋“œ์— ์ทจ์•ฝํ•  ์ˆ˜ ์žˆ๋‹ค: ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆฌ๋Š” ๋ฉ”์†Œ๋“œ ํ˜•์‹์ด ๋งค์šฐ ๋ณต์žกํ•˜๊ณ  ์ง๊ด€์ ์ด์ง€ ์•Š์•„, ์˜๋„์น˜ ์•Š๊ฒŒ ๋Š๋ฆฐ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ฑฐ๋‚˜ ์ž˜๋ชป๋œ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•  ๊ฐ€๋Šฅ์„ฑ์ด ํฌ๋‹ค.

TypeORM

  • ์ž‘๋…„๊นŒ์ง€ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋˜ ORM
  • JPA์™€ ๊ฐ€์žฅ ๊ทผ์ ‘ํ•œ ํ˜•ํƒœ์ด๋‹ค.

์ง€์› ๊ธฐ๋Šฅ

  • DataMapper์™€ย ActiveRecordย ํ˜•ํƒœ์˜ ์ฝ”๋“œ ์ง€์› (๊ฐœ์ธ์ ์œผ๋กœ DataMapper๊ฐ€ ์ข‹๋‹ค๊ณ  ์ƒ๊ฐ)
  • Entity๊ฐœ๋… ์กด์žฌ
    • ๋‹ค์–‘ํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ง€์›
    • Embedded Entities ์กด์žฌ(์—”ํ‹ฐํ‹ฐ ๋‚ด๋ถ€ ์† ๋˜๋‹ค๋ฅธ ์—”ํ‹ฐํ‹ฐ)
    • ๋ทฐ ์—”ํ‹ฐํ‹ฐ, tree ์—”ํ‹ฐํ‹ฐ ์กด์žฌ
  • Datasource ์‚ฌ์šฉ (DB ์ปค๋„ฅ์…˜ ์ถ”์ƒํ™”)
  • ์—ฐ๊ด€ ๊ด€๊ณ„ ๊ด€๋ จ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ œ๊ณต
    • Cascade ์˜ต์…˜ ์ œ๊ณต
    • ์ฆ‰์‹œ/์ง€์—ฐ ๋กœ๋”ฉ ์ œ๊ณต
  • ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ € ์ œ๊ณต
    • repository ์ƒ์„ฑ ๋ฐ ์—”ํ‹ฐํ‹ฐ ๊ด€๋ จ ์ฒ˜๋ฆฌ
  • ์ฟผ๋ฆฌ ๋นŒ๋” ์ œ๊ณต
  • ๋‹ค์–‘ํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ง€์›
    • Transactional ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ œ๊ณต(0.3์ดํ›„ ๋ฒ„์ „์—๋Š” ์ง€์› X)
    • ์ธ๋ฑ์Šค ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ
  • ์—”ํ‹ฐํ‹ฐ ์ด๋ฒคํŠธ ์ œ๊ณต

๋‚ด๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ์žฅ์ 

  • ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ง€์› - ๋‹ค์–‘ํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ฝ”๋“œ ์ˆ˜๋„ ์ค„์ด๊ณ  ๊ฐ€๋…์„ฑ๋„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ค.
  • JPA ์‚ฌ์šฉ์ž์—๊ฒŒ ๋‚ฎ์€ ๋Ÿฌ๋‹์ปค๋ธŒ - ์—”ํ‹ฐํ‹ฐ ๊ฐœ๋…๊ณผ ๋”๋ถˆ์–ด ๊ด€๋ จ ๊ธฐ๋Šฅ๋“ค์ด JPA์™€ ๊ฐ€์žฅ ์œ ์‚ฌํ•˜์—ฌ, ์ด๋ฏธ JPA๋ฅผ ๋ฐฐ์šด ์‚ฌ๋žŒ๋“ค์€ ์นœ์ˆ™ํ•˜๊ฒŒ ์‚ฌ์šฉ๊ฐ€๋Šฅ (๋‹จ, ์ผ๋ถ€ ๊ธฐ๋Šฅ์ด ์—†์–ด์„œ ๋ถˆํŽธํ•จ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Œ)
  • ๊ธ‰ํ•˜๋ฉด ์ฟผ๋ฆฌ ๋นŒ๋” ์‚ฌ์šฉ๊ฐ€๋Šฅ - ๊ฐ€์žฅ ํฐ ์žฅ์ ์ด๋ผ๊ณ  ์ƒ๊ฐ, ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋‚˜ ์ตœ์ ํ™” ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ์ฟผ๋ฆฌ ๋นŒ๋”๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ์ž‘์„ฑ ๊ฐ€๋Šฅ

๋‚ด๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ๋‹จ์ 

  • ๋ฒ„์ „ ๋ฌธ์ œ
    • ์•„์ง ์ •์‹ ๋ฒ„์ „์ด ์ถœ์‹œ๋˜์ง€ ์•Š์•„์„œ ๊ธฐ์ˆ ์  ์•ˆ์ •์„ฑ์ด ๋‚ฎ์„ ์ˆ˜ ์žˆ๋‹ค.
    • 0.3 ์ดํ›„ ๋ฒ„์ „ ๋ฌธ์ œ (ํŠธ๋žœ์žญ์…˜ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ์ง€์› X, ์ด์ „ ๋ฒ„์ „ ํ˜ธํ™˜๋ฌธ์ œ)
    • 0.4๋กœ ๋ฐ”๋€Œ๊ฒŒ ๋  ๋•Œ ๊ธฐ์กด์˜ ์ฝ”๋“œ๊ฐ€ ํ˜ธํ™˜์ด ์•ˆ๋  ์ˆ˜๋„ ์žˆ์Œ
  • ํƒ€์ž…์•ˆ์ •์„ฑ์˜ ๋ฌธ์ œ - AnyORM์ด๋ผ๋Š” ๋ณ„๋ช… ๋‹ต๊ฒŒ ํƒ€์ž…์— ๋Œ€ํ•ด ์ œ๋Œ€๋กœ ์ฒดํฌํ•  ์ˆ˜ ์—†๋‹ค.
  • ํœด๋จผ ์—๋Ÿฌ๋ฅผ ์žก์ง€ ๋ชปํ•จ - ์ฟผ๋ฆฌ์— ์ „๋‹ฌ๋˜๋Š” ํƒ€์ž…์€ ์ปดํŒŒ์ผ ๋‹จ๊ณ„์— ํ™•์ธํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ด์™€ ์—ฐ๊ด€๋œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ณต์‹๋ฌธ์„œ๊ฐ€ ๋‹ค๋ฅธ ORM์— ๋น„ํ•ด ์„ค๋ช…์ด ๋ถ€์‹คํ•˜๋‹ค๊ณ  ๋Š๋‚Œ

Prisma

  • ์ตœ๊ทผ์— ํƒ„์ƒํ•œ ORM
  • 2024๊ธฐ์ค€์œผ๋กœ ๊ฐ€์žฅ ๋งŽ์ด ๋‹ค์šด๋กœ๋“œ ํ•œ ORM์ด๋‹ค.
  • ํƒ€์ž… ์•ˆ์ •์„ฑ๊ณผ schema๋ฅผ ํ†ตํ•œ ์—”ํ‹ฐํ‹ฐ ์ƒ์„ฑ์ด ์ฃผ์š” ๊ธฐ๋Šฅ์ด๋‹ค.

์ง€์›๊ธฐ๋Šฅ

  • ๋ฐ์ดํ„ฐ ๋ชจ๋ธ์„ ์Šคํ‚ค๋งˆ ํ˜•ํƒœ๋กœ ์„ ์–ธ
    • ํ…Œ์ด๋ธ” ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์—ฐ๊ด€๊ด€๊ณ„๋‚˜ ์ธ๋ฑ์Šค, ๋ทฐ๋„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์ž‘์„ฑํ•œ ์Šคํ‚ค๋งˆ๋ฅผ DB์— ๋ฐ˜์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ํŠน์ • DB์— ์ง€์›๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์œผ๋ฏ€๋กœ ์ฃผ์˜ ํ•„์š”
  • ์ฟผ๋ฆฌ ์‹คํ–‰์„ ์œ„ํ•œ Prisma Client
    • ์Šคํ‚ค๋งˆ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž๋™์œผ๋กœ TypeScript ํƒ€์ž…์„ ์ƒ์„ฑํ•ด์คŒ โ†’ ํƒ€์ž… ์•ˆ์ •์„ฑ์ด ๋ณด์žฅ
    • ์ผ๋ฐ˜์ ์ธ CRUD์™€ ์—ฐ๊ด€ ๊ด€๊ณ„ ์ฟผ๋ฆฌ, ํ•„ํ„ฐ๋ง ์ •๋ ฌ, ํŽ˜์ด์ง€๋„ค์ด์…˜ ๋“ฑ ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณต
    • Custom validation ์ œ๊ณต
    • logging๊ณผ metrix ๊ธฐ๋Šฅ ์ œ๊ณต

๋‚ด๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ์žฅ์ 

  • ํƒ€์ž…์— ๋งค์šฐ ๊ฐ•๋ ฅํ•จ - ๋‹ค๋ฅธ ORM๊ณผ ๋‹ฌ๋ฆฌ ์ปดํŒŒ์ผ ๋‹จ๊ณ„์—์„œ ํƒ€์ž…์— ๋Œ€ํ•œ ์—๋Ÿฌ๋ฅผ ์ œ๊ณตํ•ด์ค€๋‹ค. ์ฟผ๋ฆฌ ๊ด€๋ จ ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ํƒ€์ž…์„ ์ฒดํฌํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ํŽธํ•˜๋‹ค.
  • ๋ชจ๋ธ ์„ ์–ธ์ด ๊ฐ€์žฅ ๋ณด๊ธฐ ํŽธํ•˜๋‹ค. - ๋ชจ๋ธ ์„ ์–ธ์€ sql์˜ create ์ฟผ๋ฆฌ ๋ฌธ๊ณผ ์œ ์‚ฌํ•ด์„œ ์ง๊ด€์ ์ด๋‹ค.

๋‚ด๊ฐ€ ์ƒ๊ฐํ•˜๋Š” ๋‹จ์ 

  • ๋Š๋ฆฌ๋‹ค: ๋‹ค๋ฅธ ORM์— ๋น„ํ•ด ๋Š๋ฆด ์ˆ˜๋„ ์žˆ๋‹ค. Typingํ•˜๋Š” ๊ฒƒ๊ณผ ๋”๋ถˆ์–ด์„œ ํœด๋จผ ์—๋Ÿฌ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋˜๋‹ค๋ฅธ ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ex)drop์‹œ select ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰
  • ๋ณต์žกํ•œ ์ฟผ๋ฆฌ์— ์•ฝํ•  ์ˆ˜ ์žˆ๋‹ค: nested ์ฟผ๋ฆฌ๊ฐ€ ํฌํ•จ๋˜๋Š” ์ฟผ๋ฆฌ์™€ ๊ฐ™์ด ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋‹ค.

์ฝ”๋“œ ๋น„๊ต

๋ชจ๋ธ ์„ ์–ธ

  • Sequelize

    import { Model, DataTypes } from 'sequelize';
    import sequelize from './database';
    
    class User extends Model {
      public id!: number;
      public name!: string;
      public email!: string;
      public password!: string;
      public readonly createdAt!: Date;
      public readonly updatedAt!: Date;
    }
    
    User.init(
      {
        id: {
          type: DataTypes.INTEGER,
          autoIncrement: true,
          primaryKey: true,
        },
        name: {
          type: DataTypes.STRING(100),
          allowNull: false,
        },
        email: {
          type: DataTypes.STRING,
          allowNull: false,
          unique: true,
        },
        password: {
          type: DataTypes.STRING(100),
          allowNull: false,
        },
      },
      {
        sequelize,
        tableName: 'users',
        timestamps: true,
      }
    );
    
    export default User;
  • TypeORM

    import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm';
    
    @Entity()
    export class User {
      @PrimaryGeneratedColumn()
      id: number;
    
      @Column({ type: 'varchar', length: 100 })
      name: string;
    
      @Column({ type: 'varchar', unique: true })
      email: string;
    
      @Column({ type: 'varchar', length: 100 })
      password: string;
    
      @CreateDateColumn()
      createdAt: Date;
    
      @UpdateDateColumn()
      updatedAt: Date;
    }
  • Prisma

    Prisma๋Š” schema.prisma ๋ผ๋Š” ํŒŒ์ผ์—์„œ ์„ ์–ธํ•œ๋‹ค.

    model User {
      id        Int      @id @default(autoincrement())
      name      String   @db.VarChar(100)
      email     String   @unique
      password  String   @db.VarChar(100)
      createdAt DateTime @default(now())
      updatedAt DateTime @updatedAt
    }

๋‹จ์ˆœ ์กฐํšŒ

โ€˜testerโ€™๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ ์œ ์ € ์กฐํšŒ

  • Sequelize

    import User from './models/User';
    
    const user = await User.findOne({
      where: {
        name: "tester',
      },
    });
  • TypeORM

    import { getRepository } from 'typeorm';
    import { User } from './entities/User';
    
    const userRepository = getRepository(User);
    const user = await userRepository.findOne({
      where: { name: 'tester' },
    });
  • Prisma

    import { PrismaClient } from '@prisma/client';
    
    const prisma = new PrismaClient();
    
    const user = await prisma.user.findFirst({
      where: {
        name: 'tester',
      },
    });

๋ณต์žกํ•œ ์กฐ๊ฑด ์กฐํšŒ

โ€˜testerโ€™๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์กŒ๊ณ , ๋‚˜์ด๋Š” 25์„ธ ์ด์ƒ, ๊ฐ€์ž…์ผ์ด 2024-10-30 ์ด์ƒ์ธ ์œ ์ €๋ฅผ ์กฐํšŒํ•˜๊ณ  ๋‚˜์ด์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ ํ›„ 5๋ช…์„ ์ถ”์ถœํ•œ๋‹ค.

  • Sequelize

    import { Op } from 'sequelize';
    import User from './models/User';
    
    const users = await User.findAll({
        where: {
          name: "tester",
          age: {
            [Op.gte]: 25,
          },
          createdAt: {
            [Op.gte]: new Date("2024-10-30"),
          },
        },
        order: [["age", "DESC"]],
        limit: 5,
      });
  • TypeORM

    import { getRepository, MoreThanOrEqual } from 'typeorm';
    import { User } from './entities/User';
    
    const userRepository = getRepository(User);
    const users = await userRepository.find({
      where: {
        name: "tester",
        age: MoreThanOrEqual(25),
        createdAt: MoreThanOrEqual(new Date("2024-10-30")),
      },
      order: {
        age: "DESC",
      },
      take: 5,
    });
  • Prisma

    import { PrismaClient } from '@prisma/client';
    
    const users = await prisma.user.findMany({
      where: {
        name: "๊น€๋ฏผ์ˆ˜",
        age: {
          gte: 25,
        },
        createdAt: {
          gte: new Date("2023-01-01"),
        },
      },
      orderBy: {
        age: "desc",
      },
      take: 5,
    });

์ •๋ฆฌ

๋Ÿฌ๋‹ ์ปค๋ธŒ(์‚ฌ๋žŒ๋งˆ๋‹ค ๊ธฐ์ค€์ด ๋‹ค๋ฆ„)

Prisma < TypeORM < Sequelize

JPA๋ฅผ ์•„๋Š” ๊ฒฝ์šฐ

TypeORM < Prisma < Sequelize

์„ฑ๋Šฅ

Prisma < Sequelize ? TypeORM

์„ฑ๋Šฅ์€ TypeORM์ด ๊ฐ€์žฅ ์ข‹๊ธด ํ•˜์ง€๋งŒ ๊ทน๋‹จ์ ์ธ ์ฐจ์ด๋Š” ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๋Š”๋‹ค.

ํŠนํžˆ Sequlize์™€ TypeORM์€ ์ƒํ™ฉ์— ๋”ฐ๋ผ์„œ ์†๋„ ์ฐจ์ด๊ฐ€ ๋‹ฌ๋ผ์ง€๊ฒŒ ๋˜๋ฏ€๋กœ ๋ˆ„๊ฐ€ ์šฐ์„ธ์ธ์ง€ ํ™•์‹คํ•˜๊ฒŒ ์•Œ ์ˆ˜ ์—†๋‹ค.

์‚ฌ์šฉ์„ฑ

Sequelize < TypeORM โ‰ค Prisma

์ด๊ฒƒ๋„ ๋Ÿฌ๋‹ ์ปค๋ธŒ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์‚ฌ๋žŒ๋งˆ๋‹ค ๋‹ค๋ฅผ ์ˆ˜๋„ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

Typescript๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์•„๋งˆ๋„ Prisma๊ฐ€ ๊ฐ€์žฅ ์‚ฌ์šฉ์„ฑ์ด ์ข‹์„ ์ˆ˜ ์žˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ปดํŒŒ์ผ ๋‹จ๊ณ„์— ํƒ€์ž…์— ๊ด€๋ จ๋œ ์—๋Ÿฌ๋ฅผ ์ฒดํฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ์— ๋”ฐ๋ผ ํƒ€์ž… ๊ด€๋ จ๋œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ์›ํ™œ ํ•  ์ˆ˜ ์žˆ๋‹ค.

TypeORM์€ ๋‹ค์–‘ํ•œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ง€์›ํ•˜๊ณ , ๋ณต์žกํ•œ ์ฟผ๋ฆฌ๊ฐ€ ํ•„์š”ํ•  ๊ฒฝ์šฐ query builder ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿœ ํŒ€ ๊ฐœ๋ฏธ

๐Ÿ›๏ธ ํŒ€ ๋ฌธํ™”

๊ฐœ๋ฐœ ์œ„ํ‚ค

FE

BE

Infra

๐Ÿ—ฃ๏ธ ๋ฐœํ‘œ

๐Ÿ“š ํšŒ์˜๋ก

๐Ÿ”ด ์ธํ„ฐ๋ฏธ์…˜
๐ŸŸ  1์ฃผ์ฐจ
๐ŸŸก 2์ฃผ์ฐจ
๐ŸŸข 3์ฃผ์ฐจ
๐Ÿ”ต 4์ฃผ์ฐจ
๐ŸŸฃ 5์ฃผ์ฐจ
๐ŸŸค 6์ฃผ์ฐจ

๐Ÿ’ญ ํšŒ๊ณ 

๐Ÿง‘โ€๐Ÿคโ€๐Ÿง‘ ๋ฉ˜ํ† ๋ง

Clone this wiki locally