정렬filter, pagenation 쿼리스트링으로 적용하기

정인호·2022년 10월 2일
0

팀프로젝트로 상품리스트 불러오기를 구현해 보았다.
데이터베이스의 구조는 items Table의 id(pk)를 기준으로 sub_categories Table의 item_id(fk)가 참조하고 있고, sub_categories Table의 main_category_id(pk)를 main_categories의 id(fk)가 참조하고 있다.

홈페이지에서 메인카테고리 중 한가지를 클릭 했을때 그에 해당하는 서브 카테고리들과 해당 아이템들, 태그들이 다 불러와지는 것을 구현해야 했다.

const getMainList = async ( main_category_id, sort, order, limit, offset) => {
    const result = await dataSource.query(`
    SELECT 
    items.id as items_id,
    items.name as items_name,
    items.description,
    items.price,
    items.detail,
    items.detail_image,
    items.sub_category_id,
    tags_items.id as tags_item_table_id,
    tags_items.tag_id as tags_items_table_tag_id,
    tags_items.item_id as tags_items_table_item_id,
    tags.id as tags_id,
    tags.name as tags_name,
    sub_categories.id as sub_cate_id,
    sub_categories.name as sub_cate_name,
    sub_categories.main_category_id,
    main_categories.id as main_cate_id,
    main_categories.name as main_cate_name,
    main_categories.description as main_description,
    likes.item_id as likes
    FROM items
        LEFT JOIN tags_items
            ON items.id = tags_items.item_id
        LEFT JOIN tags
            ON tags_items.tag_id = tags.id
        INNER JOIN sub_categories
            ON items.sub_category_id = sub_categories.id
        INNER JOIN main_categories
            ON sub_categories.main_category_id = main_categories.id
        LEFT JOIN likes
            ON items.id = likes.item_id
        INNER JOIN main_categories
            ON sub_categories.main_category_id = main_categories.id
        WHERE main_categories.id = ${main_category_id} 
        AND sub_categories.main_category_id = ${main_category_id}
        ORDER BY ${sort} ${order} LIMIT ? OFFSET ?
`, [ limit, offset]
); 
return result;
}

따라서 위 코드를 보면 알 수 있듯이, items 테이블을 기준으로 생각 했을 때 main과 sub를 inner join으로 가져왔고, tags table은 모든 아이템에 tag가 붙어있는게 아니기 때문에 inner join으로 가져오면 null값이 있는 column은 불러와지지 않아서, left join으로 가져왔다.(likes도 마찬가지)
필요한 모든 것을 다 불러온 후 메인 카테고리를 클릭했을 때 그에 해당하는 것들이 페이지에 다 나오게 하기 위해선 여러 방법이 있겠지만, 여기선 쿼리스트링을 이용해서 프론트에서 요청이 들어왔을때 쿼리스트링으로 받아서 main_categories id에 해당하는 데이터베이스에 저장된 정보들을 불러오게 조건문을 where절로 작성 했다.

WHERE main_categories.id = ${main_category_id} 
        AND sub_categories.main_category_id = ${main_category_id}

만약 쿼리스트링으로 들어온 main_categories.id가 1이라면, main_categories.id가 1이고, sub_categories.main_category_id도 1인 데이터들만 가져오라는 조건문이다. 이렇게 하면 바지라는 main_category가 있고 그 id가 1이라면 그에 해당하는 sub_categories 테이블의 main_category_id가 1인 청바지, 슬랙스 등의 sub_categories가 불러와질 것이고 또 그 아래에 있는 items과 tag, likes가 불러와 질 것이기 때문이다.

ORDER BY ${sort} ${order} LIMIT ? OFFSET ?

order by 뒤에 오는 sort는 정렬 기준, order는 오름차순과 내림차순을 결정하며, limit과 offset은 pagenation을 결정한다.

const getAll = asyncWrap(async (req, res) => {
    const { sort, order } = req.query
    let { limit, offset } = req.query

    limit = limit || 50
    offset = offset || 0

여기에 요청으로 들어오는 쿼리스트링들은 controller단에서 요청이 들어오면 쿼리스트링으로 각 변수에 담아주고, 이를 Dao단 까지 보내준다.
pagenation은 요청으로 안들어올 경우 여기선 50, 0으로 지정해 주었듯이 따로 처리를 해줘야 한다.

profile
경제학과를 졸업후 개발에 뛰어든 햇병아리입니다.

0개의 댓글