kakasoo

Repository 최대한 예쁘게 써보기 ( 검색, 정렬, 필터링 ) 본문

프로그래밍/NestJS

Repository 최대한 예쁘게 써보기 ( 검색, 정렬, 필터링 )

카카수(kakasoo) 2022. 6. 11. 17:44
반응형
// NOTE: 예시로 작성한 코드
async searchUser(search: string, orderName: string, order: 'DESC' | 'ASC') {
    let query = this.userRepository
        .createQueryBuilder('user')
        .leftJoinAndSelect('user.department', 'user')
        .where('user.isBot = false');

    if (search) {
        query = query.andWhere('user.name ILIKE :search OR department.name ILIKE :search', {
            search: `%${search}%`,
        });
    }

    if (orderName && order) {
        return await query.orderBy(orderName, order).addOrderBy('createdAt', 'DESC').getMany();
    }
    return await query.orderBy('createdAt', 'DESC').getMany();
}

 

Typeorm이 8버전, nestjs의 Typeorm이 0.2 버전일 때에는, 검색이나 정렬 조건 등을 클라이언트로 받을 시, 이런 구조로 만드는 게 가장 깔끔했다. 조건문을 이용해서, 쿼리를 점진적으로 만들어가는 방식이었다. 하지만 이 방식은 쿼리빌더를 사용 중이므로, 실행 전에 에러를 미리 발견할 수 없었고, where과 addWhere, orderBy, addOrderBy 등, 순서가 중요한 쿼리 명령어에 대해서는 분기 처리를 할 때 쿼리를 각각 작성해줘야 하는 문제가 있었다. 위 코드에서도 orderName, order에 대한 쿼리 문은 createdAt을 마지막으로 정렬하기 위해, 각각 쿼리를 작성해서 반환해주고 있다.

 

 

// NOTE: 예시로 작성한 코드

async searchUser(search: string, orderName: string, order: 'DESC' | 'ASC') {
    const users = await this.userRepository.find({
        relations : { department : true },
        where: [
            { isBot: false, ...(search && {name : ILike(`%${search}%`)})},
            { isBot: false, ...(search && { department: {name : ILike(`%${search}%`)})}
        ],
        order: {
            ...(orderName && order && { orderName: order }),
            createdAt: 'DESC',
        },
    });
}

 

위 코드는 이런 식으로 바꿀 수 있다. 이제 Repository에서 join된 테이블의 내부에도 where문, order를 작성할 수 있게 됐기 때문에 훨씬 더 편리한 구조가 되었다. where과 같은 find option, condition 등을 타입을 지정한 후 마지막에 넣어줄 수도 있지만, 그보다도 이제, if 문이나 별도 작업 없이 바로 작성할 수 있게 되었다. &&나 삼항 연산자를 이용해서, 조건에 따라 다른 쿼리가 들어가게 해주고, where절의 경우, 배열로 넣으면 OR 연산이 된다는 점을 이용해 search를 더 쉽게 해준다.

반응형