티스토리 뷰

MyBatis를 활용해서 여러가지 프로젝트를 하다보면 같은 MyBatis인데도 다른 경우가 있다. 바로 제목에 나온것처럼 Mapping 방식의 차이가 있을수 있기 때문이다. Query ID Mapping 방식 vs Mapper Interface 방식 으로 프로젝트마다 사용되는 방식이 다르다. "이게 더 좋으니 이걸로 쓰세요" 하려는 글은 아니고 이런 방식이 있고 이런 특징들이 있다 라는걸 알리고자 한다. 


Query ID Mapping 방식

Query ID Mapping 방식은 필자에겐 가장 익숙하다. 왜냐면 가장 많이 써온 방식이기 때문이다. 이전의 포스팅에서 MyBatis를 설명할때도 이 Query ID Mapping 방식으로 설명을 했었다. 

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="commonCode">
    <select id="getCommonCodeList" resultType="HMap">
	SELECT	  CODE_NAME
      		, TO_CHAR(UPD_DTM, 'YYYY-MM-DD') AS UPD_DTM
	FROM      COMMON_CODE
    </select>
</mapper>

이런 Query를 정의한 파일이 있다고 하자.

Query ID 라는것은 2번째줄의 mapper namespace + 3번째줄의 statement id에 해당하는 것을 말한다.

Namespace ID + Statement ID = Query ID 라는 것이다. 즉 위와 같은 경우는 Query ID는 commonCode.getCommonCodeList 이다. 이 Query ID는 유일해야 한다. 

 

@Repository
public class SampleDAO {

    @Autowired
    private SqlSessionTemplate sqlSession
 
    /*insert, delete, update, select 메소드 모두 재정의*/
    public Object select(String queryId, Object params){
        return sqlSession.select(queryId, params);
    }

    public List selectList(String queryId, Object params){
        return sqlSession.selectList(queryId, params);
    }
}

그래서 호출을 하는 쪽에서는 Query ID 를 통해서 Query 와 Mapping을 한다. queryId에 해당하는 부분이 위의 예시와 연결지어보면 "commonCode.getCommonCodeList" 가 들어가야 하는 것이다. MyBatis의 초창기 버전부터 이런 구조였기 때문에 거의 대부분의 사람들이 아는 방식이다. 

장점으로는 CommonDao 같은걸 사용하면 코드량이 많이 줄어들 수 있고 사용하기 어렵지 않다. 

Query ID를 작성하는 과정에서 오타를 조심해야 한다. 그리고 위의 예제처럼 단건, 다건의 경우 메소드를 구분하여 사용해야 하는 점 정도가 단점이라고 생각한다. 

 

 

Mapper Interface 방식

그다음은 Mapper Interface 방식이다. 위에서도 언급했지만 사용하는 방법의 차이일 뿐이다. MyBatis 3.0 이후의 버전부터 사용할 수 있고 SQL Query 문을 interface 방식으로 호출해서 Mapper Interface 방식이라고 한다. 

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.oingdaddy.sample.repository.SampleRepository">
    <select id="getCommonCodeList" resultType="HMap">
	SELECT	  CODE_NAME
      		, TO_CHAR(UPD_DTM, 'YYYY-MM-DD') AS UPD_DTM
	FROM      COMMON_CODE
    </select>
</mapper>

위의 Query Mapping 방식과 동일한것 같지만 mapper namespace를 정의한 부분이 살짝 다르다. 이 Query 파일과 매핑시킬 interface를 이곳에서 위와 같이 연결을 해준다. 전체 패키지 경로를 기술해주자. 

그리고 Statement ID에 해당하는 부분은 뒤에 작성할 Repository의 method 명이 되는것을 알아두자. 

 

com.oingdaddy.sample.repository.SampleRepository.java

package com.oingdaddy.sample.repository;

@Repository
public interface SampleRepository {
    
    List<Object> getCommonCodeList();
    
}

그리고 위의 Query ID 방식은 Repository를 정의한것이 class였는데 Mapper Interface방식에서는 interface여야 한다. 이곳에 메소드는 위의 Query에서 정의한것을 사용하고 return type만 지정을 해주면 위의 Query ID 방식처럼 단건 / 다건을 구분하는 method를 사용하지 않아도 된다. 
하드코딩하지 않으므로 실수를 줄여줄 수 있고 한눈에 어떤 쿼리목록들이 있는지 파악이 용이한것이 장점이며, 코딩이 몇줄 더 늘어나는 단점은 있다. 

 

결론 : 조금이라도 코드가 간결해지길 원한다면 Query ID Mapping 방식을 사용하고 조금 더 오류발생 가능성이 적고 체계적인 관리를 원한다면 Mapper Interface 방식이 괜찮은것 같다. 

 

끝!

 

댓글
최근에 올라온 글
최근에 달린 댓글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31