Back-end/Spring

[Mybatis] resultMap을 이용해서 쿼리 서브 정보 받아오기 (left join 정보 받아오기)

shoney9254 2023. 7. 15. 17:54
반응형

jpa를 사용하는 환경이면 @OneToMany를 사용해서 Dto안의 List<Dto>를 반환하는 것을 쉽게 구현할 수 있다. 하지만, mybatis에서는 resultMap을 이용해서 서브정보를 쿼리로 반환해야 한다. (xml에 resultMap을 사용하는 예시를 바로 보려면 2-2. 쿼리작성 부터 보시면 됩니다.)

 

1. 요구사항 

프론트에서 아래와 같은 json 포맷으로 요구했다. 메인 정보 안에 서브정보를 리스트로 반환해야 한다.

요구사항 JSON

[
  {
    "id": "an001",
    "title": "데브옵스개발팀에 초대합니다.",
    "content": "오세요",
    "skills": [
      {
        "skillId": "sk001",
        "skNm": "java"
      },
      {
        "skillId": "sk002",
        "skNm": "python"
      },
      {
        "skillId": "sk003",
        "skNm": "react"
      }
    ]
  },
  {
    "id": "an002",
    "title": "춘개발자를 모집합니다.",
    "content": "오십쇼",
    "skills": [
      {
        "skillId": "sk002",
        "skNm": "python"
      },
      {
        "skillId": "sk004",
        "skNm": "mySql"
      }
    ]
  }
]

위처럼 반환하기 위해서는 여러 가지 방법이 있겠지만, resultMap을 사용해서 한 번에 반환해 보자.

 

2. 해결방법

2-1. dto를 2개 만든다. 

위에 json 내용을 보면 공고에 대한 정보(=dto) 하나 안에, 스킬에 관한 서브정보(=dto)로 2개의 dto가 필요할 것을 예상할 수 있다.

2-1-1. 공고 dto

AnnouncementDto

@Data
public class AnnouncementDto {
    String id;
    String title;
    String content;
    List<SkillDto> skills;
}

2-1-2. 스킬 dto

SkillDto

@Data
public class SkillDto {
    String skillId;
    String skNm;
}

 

2-2. 쿼리 작성

xml에 쿼리를 작성할 때, resultMap을 사용하면 된다.

쿼리

    <resultMap id ="resultMap" type="com.lgcns.tct.mcu.dto.AnnouncementDto">
        <id property="id" column="id" />
        <id property="title" column="title" />
        <id property="content" column="content" />
        <collection property="skills" ofType="com.lgcns.tct.mcu.dto.SkillDto">
            <id property="skillId" column="skill_id"/>
            <id property="skNm" column="sk_nm"/>
        </collection>
    </resultMap>
   
    <select id="getAnnouncementListWithSkill" resultMap="resultMap">
        SELECT ta.Id, ta.title, ta.content, tas.skill_id, ts.sk_nm
        FROM kickboard_svc.t_announcement ta
        LEFT OUTER JOIN kickboard_svc.t_announcement_skill tas
            ON ta.Id = tas.an_id
        INNER JOIN kickboard_svc.t_skill ts
            ON tas.skill_id = ts.sk_id
    </select>

위처럼, resultMap을 사용해서 메인 dto, 서브 dto 관계를 정의를 해서 쿼리문에서 사용하면 된다. 

 

 

3. 결과 확인

vscode에서는 Thunder Client로 api를 테스트할 수 있다. 아래 캡처 화면을 보면 정상적으로 반환되는 것을 확인할 수 있다.

 

 

 

 

 

 

 

 

반응형