[TypeORM] Active-record 패턴 사용해보기

18980 단어 typeOrmtypeOrm

시작

TypeORM을 이용하는 방법 중 data-mapper, active-recode패턴이 있다. 이번 글에서는 Active-recode에 대해 알아보겠습니다.

Active-recode패턴을 사용한 이유

현재 진행하고 있는 프로젝트의 규모가 크고, 복잡하지 않기 때문에 Active-record패턴을 이용해 빠르게 개발한 후, 리팩토링 과정에서 data-mapper패턴이 필요하면 옮길 예정이라 Active-record패턴을 사용했습니다.

Active-record란?

각 entity에서 정의한 쿼리 메소드들을 이용해 entity객체를 데이터베이스에 접근하는 패턴입니다. 그리고 entity파일들은 find, save등의 기본 기능을 제공해주는 BaseEntity를 상속받아야 합니다.

  • BaseEntityrepository의 표준 기능들을 다 가지고 있기 때문에 repository, EntityManager를 사용하지 않아도 됩니다.
  • repository는 data-mapper패턴에서 사용됩니다.
  • TypeORM 공식문서에 나와있는 내용입니다.

사용 코드

공식문서 코드를 보고 싶으시면 여기를 참고해주세요.

entity/mapping.ts

import {Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, Timestamp, ManyToOne, JoinColumn, OneToMany, BaseEntity} from "typeorm";
import { Alarm } from './Alarm';
import {BabySitter} from './BabySitter'
import {Parent} from './Parent'
import { WorkDiary } from './WorkDiary';

@Entity()
export class Mapping extends BaseEntity {

    @PrimaryGeneratedColumn()
    mappingId: number;

    @CreateDateColumn({})
    createdAt: Timestamp

    // 1: 매핑된거 2: 대기 3: 거절
    @Column({default : 2})
    status : number

    // mapping(N) <->  baby sitter(1)
    @ManyToOne(
        () => BabySitter, 
        babySitter => babySitter.mapping, { nullable: false, onDelete: 'CASCADE' })
    @JoinColumn({name: "bsId"})
    babySitter : BabySitter

    
    // mapping(N) <->  baby parent(1)
    @ManyToOne(
        () => Parent, 
        parent => parent.mapping, { nullable: false, onDelete: 'CASCADE' }
        )
    @JoinColumn({name: "parentId"})
    parent : Parent


    // Mapping(1) <-> Alarm(N)
    @OneToMany(
        () => Alarm,
        alarm => alarm.mapping,{ nullable: false, onDelete: 'CASCADE' }
    )
    alarm: Alarm[];


    // Mapping(1) <-> WorkDiary(N)
    @OneToMany(
        () => WorkDiary,
        workDiary => workDiary.mapping,{ nullable: false, onDelete: 'CASCADE' }
    )
    diary: WorkDiary[];

    // 부모 ID를 기준으로 매핑되어 있는 보모 정보를 반환
    static async findMappingList(parentId: number) {
        return await this.createQueryBuilder("mapping")
            .leftJoinAndSelect("mapping.babySitter", "babySitter")
            .where("mapping.parentId = :parentId", { parentId: parentId })
            .getMany();
    }


    // 이미 동일한 요청이 있는 경우 체크하기 위한 함수
    static async checkDuplicate(parentId: number, bsId: number){

        return await this.createQueryBuilder("mapping")
            .where("mapping.parentId = :parentId", {parentId:parentId})
            .andWhere("mapping.bsId = :bsId", {bsId:bsId})
            .getMany();
    }
}
  • entity파일에 static을 이용해 쿼리 메소드 정의

controllers/mapping.ts

import { NextFunction, Request, Response } from 'express';
import { BabySitter } from '../entity/BabySitter';
import { Mapping } from '../entity/Mapping';

const findParentList = async (req:Request, res: Response, next: NextFunction) => {
    try{
        const bsId : number = +req.params.bsId; 
    
    await BabySitter.findById(bsId)
    const result = await Mapping.findMappingParentList(bsId);

    
}

export default{
    findParentList
}
  • entity파일에서 정의한 static 쿼리 메소드를 이용해 데이터베이스 접근

controllers/babysitter.ts

const inputBSInfo = async (req:Request, res:Response, next:NextFunction) => {
    const {age, gender, region, career} : BsInputInfo = req.body

    // req.params.userId -> string이라 number로 변환
    const userId: number = +req.params.userId;

    const user = await User.findOne({userId: userId});

    const bs = new BabySitter();
    bs.age = age;
    bs.gender = gender;
    bs.region = region;
    bs.career= career;
    bs.user = user;

    await bs.save()
}
  • entity에서 상속받은 BaseEntity의 기능인 save()를 이용해 entity객체 저장

좋은 웹페이지 즐겨찾기