DAY18

yejichoi·2022년 11월 28일
0
post-thumbnail

1.Algorithm Study

2. Backend Class

1 : 1 테이블 생성

// product.entity.ts
// typeorm 
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Product {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column(//타입지정)
  name: string;

  @Column()
  description: string;

  @Column()
  price: number;

  @Column()
  isSoldout: boolean;

  @JoinColumn()
  @OneToOne(() => ProductSaleslocation) // 1 : 1 
  productSaleslocation: ProductSaleslocation;
}
  • @Entity : class가 실행될 때, typeorm에 의해 Entity 테이블을 만들어줌
  • @PrimaryGeneratedColumn(' ') : 자동으로 생성될 값의 컬럼
    • increment : 숫자로 데이터가 쌓일때마다 숫자가 하나 하나씩 올라가는 PK 키를 만들 수 있음
    • uuid ( = Universal Unique IDentifier ) : 중복되지 않는 고유한 PK 키
  • @Column({ type : ‘text’ }) : ERD에서 타입을 지정해주었는데, 엔티티에서 타입을 원하는대로 지정해 줄 수 있음. 정해주지 않으면( 빈 괄호로 둘 경우) default 값
  • boolean 타입을 만들때는 컬럼명 앞에 is 를 붙여줘서 이름만 보고도 boolean 타입인 것을 알 수 있게 해줌
  • @OneToOne() : 두 테이블의 관계를 나타내는 것으로 @OneToOne( ) 은 한쪽에만 쓰거나, 양쪽에 모두 써줄 수 있음
  • @JoinColumn() : 두 테이블을 하나로 합쳐서 데이터를 가져와야하기에 사용하였으며, 한쪽 테이블에만 적어줘야함
  • productSaleslocation 의 타입은 ProductSaleslocation class 자체이기에 import 를 해왔습니다.

N : 1 테이블 생성

// product.entity.ts
@Entity()
export class Product {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  name: string;

  @Column()
  description: string;

  @Column()
  price: number;

  @Column()
  isSoldout: boolean;

  @JoinColumn()
  @OneToOne(() => ProductSaleslocation)
  productSaleslocation: ProductSaleslocation;

  //@JoinColumn() 생락갸능 
  @ManyToOne(() => ProductCategory) // N : 1 관계 
  productCategory: ProductCategory;
}
  • @ManyToOne() : N : 1 관계를 나타내는 데코레이터
  • @JoinColumn() : Many 부분에 해당하는 테이블(product)에서는 JoinColumn( ) 이 생략 가능
    • @ManyToOne( ) : @JoinColumn( ) 생략가능
    • @OneToOne( ) : @JoinColumn( ) 반드시 필요

N : M 테이블 생성

중간테이블 존재 => 따로 만들어주는 것이 아니라 연결을 해줄 때 자동으로 생성되는 테이블

// prodcutTag.entity.ts

import { Product } from 'src/apis/products/entities/product.entity';
import { Column, Entity, ManyToMany, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class ProductTag {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  name: string;
  
// 연결되는 두 테이블 모두 필요함 
  @ManyToMany(() => Product, (products) => products.productTags)
// products는 productTags에 있는 products로 연결된다는 의미 
  products: Product[];
}
  • @ManyToMany() : N :M의 관계를 가질 때는 두 테이블 모두 컬럼을 추가하여 연결해 주어야함
  • (products) => products.productTags : products 입장에서의 productTags 와의 관계를 명시해 준 것으로, N : M 관계에서는 두 테이블 모두 관계를 나타내 주어야함
  • Product[] : 하나의 태그에 상품이 여러개 해당될 수 있기에 배열로 나타내는 것
// product.entity.ts
@Entity()
export class Product {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  name: string;

  @Column()
  description: string;

  @Column()
  price: number;

  @Column()
  isSoldout: boolean;
  // soldedAt: Date

  @JoinColumn()
  @OneToOne(() => ProductSaleslocation)
  productSaleslocation: ProductSaleslocation;

  @ManyToOne(() => ProductCategory)
  productCategory: ProductCategory;

  @ManyToOne(() => User)
  user: User;

  @JoinTable() // 기준이 되는 한 쪽에만 작성 
  @ManyToMany(() => ProductTag, (productTags) => productTags.products)
  productTags: ProductTag[];
} 
  • @JoinTable() : N : M 관계에서 생성되는 중간 테이블을 자동으로 만들어 주는 것으로 기준이 되는 테이블 한 쪽에만 작성
  • (productTags) => productTags.products : productTags 입장에서의 prodcuts 와의 관계를 명시해 준 것으로, N : M 관계에서는 두 테이블 모두 관계를 나타내 주어야함
  • ProductTag[] : 하나의 상품이 여러개의 태그에 해당 될 수 있기에 배열로 나타내는 것

Dbeaver를 사용한 테이블 확인

// app.module.ts

import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { GraphQLModule } from '@nestjs/graphql';
import { TypeOrmModule } from '@nestjs/typeorm';
import { BoardModule } from './apis/boards/board.module';

@Module({
  imports: [
    BoardModule,
    ConfigModule.forRoot(),
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: 'src/commons/graphql/schema.gql',
    }),
    TypeOrmModule.forRoot({
      type: process.env.DATABASE_TYPE as 'mysql',
      host: process.env.DATABASE_HOST,
      port: Number(process.env.DATABASE_PORT),
      username: process.env.DATABASE_USERNAME,
      password: process.env.DATABASE_PASSWORD,
      database: process.env.DATABASE_DATABASE, // env파일 수정
      entities: [__dirname + '/apis/**/*.entity.*'], // 수정
      synchronize: true,
      logging: true,
    }),
  ],
})
export class AppModule {}

집계, 정렬, 서브 쿼리

SUM

select name, SUM(price) 
		from product
	group by name; 

MAX

select name, MAX(price) 
		from product
	group by name; 

ASC (오름차순)

select name, price, isSoldout 
		from product
	order by price asc;

DESC (내림차순)

select name, price, isSoldout 
		from product
	order by price desc;

서브쿼리

하나의 SQL 문에 포함되어 있는 또 다른 SQL 문을 의미
서브 쿼리를 포함한 쿼리문을 실행한다면, 서브 쿼리가 먼저 실행이 된 후 메인 쿼리가 실행

select name, price, isSoldout,
		(select max(price) from product) as maxPrice
	from product;

(select max(price) from product)을 사용하여 상품 테이블에서 가격이 최대값인 상품을 조회하여 그 가격이름을 as를 통해 maxPrice로 바꿔서 상품 데이터를 조회한다는 의미

3. HW

0개의 댓글