routine.entity.ts

import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
import { Timestamps } from '../../TimeStamp.entity';
import { User } from '../../user/domain/User.entity';
import { RoutineToExercise } from '../../routineToExercise/domain/RoutineToExercise.entity';

@Entity()
export class Routine extends Timestamps {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @ManyToOne(() => User, (user) => user.routines)
  public user: User;

  @OneToMany(() => RoutineToExercise, (routineToExercise) => routineToExercise.routine)
  public routineToExercises: RoutineToExercise[];

}

 

exercise.entity.ts

import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
import { Timestamps } from '../../TimeStamp.entity';
import { BodyPart } from './bodyPart.enum';
import { WorkoutLogToExercise } from '../../workoutLogToExercise/domain/WorkoutLogToExercise.entity';
import { RoutineToExercise } from '../../routineToExercise/domain/RoutineToExercise.entity';

@Entity()
export class Exercise extends Timestamps {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ type: 'enum', enum: BodyPart })
  bodyPart: BodyPart;

  @Column()
  exerciseName: string;

  @OneToMany(() => WorkoutLogToExercise, (workoutLogToExercise) => workoutLogToExercise.exercise)
  workoutLogToExercises: WorkoutLogToExercise[];

  @OneToMany(() => RoutineToExercise, (routineToExercise) => routineToExercise.exercise)
  routineToExercises: RoutineToExercise[];

}

 

routineToExercises.entity.ts

import { Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { Exercise } from '../../excercise/domain/Exercise.entity';
import { Routine } from '../../routine/domain/Routine.entity';

@Entity()
export class RoutineToExercise {
  @PrimaryGeneratedColumn()
  id: number;

  @ManyToOne(() => Routine, (routine) => routine.routineToExercises)
  public routine: Routine;

  @ManyToOne(() => Exercise, (exercise) => exercise.routineToExercises)
  public exercise: Exercise;
}

 

 

routine 에서  유저 A 가 게시한 routine 목록을 검색하고 이와 연관된 excersie 값도 같이 검색한다. 이때 모든 값을 다 보여주지 않고 선택된 값만 반환 받는다.

const routines = await this.routineRepository
      .createQueryBuilder('routine')
      .leftJoinAndSelect('routine.routineToExercises', 'routineToExercises')
      .leftJoinAndSelect('routineToExercises.exercise', 'exercise')
      .innerJoin('routine.user', 'user')
      .select([
        'routine.id',
        'routine.name',
        'routineToExercises.id',
        'exercise.id',
        'exercise.exerciseName',
        'exercise.bodyPart',
      ])
      .where('routine.name = :name AND user.id = :userId', { name: 'test', userId: user.id })
      .getMany();

용어 설명

 

  • createQueryBuilder() : SQL 쿼리를 보다 세밀하게 제어할 수 있게 해주는 메소드입니다
    •  createQueryBuilder('routine')
      • routineRepository 를 이용하여 생성된 쿼리에서 Routine 엔티티를 참조할 때 사용할 별칭을 routine 으로 합니다.
  • .leftJoinAndSelect() : 지정된 엔티티와 연결된 다른 엔티티를 "왼쪽 조인"으로 불러오며, 결과에 포함시키기를 원하는 필드를 선택적으로 로드합니다.
    • .leftJoinAndSelect('routine.routineToExercises', 'routineToExercises')
      • Routine 과 RoutineToExercises 사이에 설정된 관계를 기반으로 왼쪽 조인을 수행하고, routineToExercises라는 별칭을 사용하여 조인된 결과를 선택합니다.
      • 이 조인은 Routine 과 RoutineToExercises 사이의 관계를 탐색하고 관련 데이터를 반환합니다.
      • 일치하는 항목이 없어도 Routine 데이터는 반환합니다.
  • .innerJoin() : 조건을 만족하는 데이터만 결과에 포함시키는 "내부 조인"을 수행합니다. 연결된 테이블의 매칭되는 행이 없다면 결과에서 해당 데이터를 제외합니다.
    • .innerJoin('routine.user', 'user')
      • Routine 테이블의 user 필드와 User 테이블에서 일치하는 항목만 결과에 포함시킵니다.
  • .where() :쿼리에서 데이터를 필터링할 조건을 설정하는 부분입니다.
    • .where('routine.name = :name AND user.id = :userId', { name: 'test', userId: 3 })
      • 조건을 설정 : routine.name = :name AND user.id = :userId
        • routine.name = :name 은 Routine 테이블의 name 필드가 쿼리 파라미터 :name으로 지정된 값과 일치해야 한다는 것을 의미합니다.
        • :name, :userId와 같은 표현은 쿼리에 사용될 변수의 이름으로 자유롭게 지정할 수 있습니다.
      • 파라미터 바인딩: { name: 'test', userId: user.id }
        • name 필드가 'test' 이고 userId 필드가 user.id 에 일치하는 데이터만 반환합니다.

 

+ Recent posts