BackEnd/Spring

[Spring] MyBatis 사용 시 resultType 에 InnerClass 사용하기

Wonol 2022. 12. 10. 10:50
반응형

종종 Spring + MyBatis 개발을 하던 도중에 ResultMap 또는 ResultType 에 InnerClass 로 선언하고자 하는 경우가 있다.


1. 파일 구성

- 간단하게 예제를 통해서 진행해보겠습니다.

- ResultType 에서 사용하고자 하는 파일은 아래와 같습니다.(Response 를 사용)

실제 개발에서는 DB의 값을 그대로 전달하는 것은 좋은 방법이 아니지만, 간단한 테스트를 위해서 바로 사용하였습니다.
public class TodoDto {

    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Request {
        private String item;
        private boolean completed;
    }

    @Data
    @AllArgsConstructor
    public static class Response {
        private String item;
        private String date;
        private boolean completed;
        private String time;
    }
}

- 간단한 Controller, Service 및 Mapper 입니다.

@RestController
@Slf4j
@RequiredArgsConstructor
public class TestController {

    private final MybatisTestService mybatisTestService;

    @GetMapping("/mybatis")
    public void test(){
        List<TodoDto.Response> mybatisTest = mybatisTestService.testSelect();

        for(TodoDto.Response test : mybatisTest){
            log.info("Result : " + test.toString());
        }
    }
}

- DB 조회 값을 TodoDto 의 InnerClass 인 Response로 받도록 합니다.

@Service
@RequiredArgsConstructor
public class MybatisTestService {

    private final MybatisTestMapper mybatisTestMapper;

    public List<TodoDto.Response> testSelect() {
        return mybatisTestMapper.testSelect();
    }
}
@Mapper
public interface MybatisTestMapper {
    List<TodoDto.Response> testSelect();
}

2. 사용방법

- 일반적으로 Mapper.xml 파일에서 ResultType 을 선언할 때는 아래와 같이 사용합니다.

<select id="testSelect" resultType="com.todo.blog.model.TodoDto">
    SELECT item, date, completed, time
    FROM TODO
</select>

- 하지만 위와 같이 사용하면 TodoDto 의 InnerClass 로 접근하지 못해서 컴파일 도중 ClassNotFoundException 이 발생하게 됩니다.

- InnerClass 를 사용하기 위해서는 아래와 같이 닷(.)연산자 대신 $연산자로 바꿔서 사용하면 됩니다.

<select id="testSelect" resultType="com.todo.blog.model.TodoDto$Response">
    SELECT item, date, completed, time
    FROM TODO
</select>
Java 에서 프로그래밍할 때는 Class 안에서 InnerClass 에 접근할 때, 닷(.)을 사용합니다.
하지만 특정 클래스를 읽어와야 하는 경우 ClassLoader 에서는 Package namespace 는 닷(.)으로 구분하고, 클래스와 InnerClass 의 namespace 는 $ 로 구분합니다.

참고

- https://secondmemory.kr/210

- https://hashcode.co.kr/questions/1753/mybatis%EC%97%90%EC%84%9C-inner-class-%EC%82%AC%EC%9A%A9%EB%B0%A9%EB%B2%95%EC%9D%B4-%EA%B6%81%EA%B8%88%ED%95%A9%EB%8B%88%EB%8B%A4

반응형