MyBatis로 SELECT 해보자

zzee22su·2022년 5월 23일
0

나의 실수..ㅎ

목록 보기
2/2
post-thumbnail

단순히 DB에 저장되어 있는 API 정보를 가져오는 작업이 필요하여 해당 API를 생성하였다.

api 정보를 가져오는 로직이 정의되어 있는 함수 호출.

    @GetMapping(value = "/apiInfo", produces = "application/json;charset=utf-8")
    public Callable<Response> getApiInfo(final HttpServletRequest request) throws Exception {
        return () -> service.getApiInfo();
    }

필요한 api 정보를 가져오는 로직 구현

    public Response getApiInfo() {
        Response result = Response.from();
        ApiInfo apiInfo;
        apiInfo = mapper.getApiInfo();
        result.setData("apiInfo", apiInfo);
        return result;
    }

ApiInfo 클래스
: DB에서 조회한 값을 아래와 같은 몸체로 저장하기 위해 생성.

@Data
public class ApiInfo {
    private String url;
    private String key;
    private boolean isEnable;
}

mapper.xml

	<select id="getApiInfo" resultType="ApiInfo">
		SELECT apiUrl,
			   apiKey
		FROM prediction_api
		WHERE isEnable IS FALSE
	</select>

API 실행 결과
: DB에 데이터가 저장되어 있음에도 불구하고 null 값이 반환되었다.

원인

getApiInfo() 를 보면 DB에서 SELECT 한 값을 apiInfo에 저장하고 있다.

apiInfo = mapper.getApiInfo();

그리고 mapper에서 apiUrlapiKey를 조회하는 select 쿼리가 잘 정의되어 있는 것으로 보인다.

	<select id="getApiInfo" resultType="ApiInfo">
		SELECT apiUrl,
			   apiKey
		FROM api
		WHERE isEnable IS FALSE
	</select>

그렇다면 api 테이블에 apiUrlapiKey가 어떻게 정의되어 있는지 DB를 확인해보자.

DB에 저장되어 있는 컬럼명과 동일한 것을 확인, 그리고 쿼리도 정상적으로 실행되었다.(로그로 확인)

그렇다면 ApiInfo 클래스를 확인해보자.
ApiInfo에서 String으로 url, key를 선언해놓았었다.

@Data
public class ApiInfo {
    private String url;
    private String key;
    private boolean isEnable;
}

아...

apiInfo에 select한 결과 값을 저장하려는데 DB에 정의되어있는 apiUrl,apiKeyApiInfo 클래스에는 존재하지 않아 null로 넘어오는 것이였다...(ApiInfo에는 url, key로 선언했기 때문에...)


이제 원인을 알았으니! 고쳐보자~!

방법은 2가지로 보인다.

방법 1) ApiInfo클래스에 정의되어 있는 변수명을 DB에 저장되어 있는 값으로 동일하게 변경한다.

@Data
public class ApiInfo {
    private String apiUrl;
    private String apiKey;
    private boolean isEnable;
}

혹시 코드 내에 get 하는 곳이 있다면 그 부분도 모두 변경해줘야 한다.
ex) apiInfo.getUrl() -> apiInfo.getApiUrl()

+(단축키 shift+f6로 변수명 일괄 변경 및 적용이 가능하다.)


방법 2) mapper.xml에 있는 기존 select문에 as를 사용하여(별칭) 아래와 같이 수정한다.

	<select id="getApiInfo" resultType="ApiInfo">
		SELECT apiUrl as `url`,
			   apiKey as `key`
		FROM prediction_api
		WHERE isEnable IS FALSE
	</select>

결과

ㅎㅎ 이거지. 😁 (방법1,2 모두 잘 된다!)

개선

추가로, DB에 저장된 값이 존재하지 않으면 미리 정의해둔 상수값을 조회하도록 구현하였다.
(DB에 저장되어 있는 isEnable값이 true로 변경되었을 때, 검색 되지 않을 것을 대비.)

    public Response getApiInfo() {
        Response result = Response.from();
        ApiInfo apiInfo;
        apiInfo = predictionMapper.getApiInfo();
        if(apiInfo==null) {
            apiInfo = new ApiInfo();
            apiInfo.setUrl(DEFAULT_API_URL);
            apiInfo.setKey(DEFAULT_API_KEY);
            apiInfo.setEnable(false);
        }
        result.setData("apiInfo", apiInfo);
        return result;
    }

이상! 끝!

profile
BackEnd/Android

0개의 댓글