[MyBatis] 쿼리문을 재사용하는 방법(sql, include)
- DB접근기술/Mybatis
- 2022. 8. 25. 16:05
native 쿼리를 직접 작성하는 JDBCTemplate이나 MyBatis 같은 기술은 항상 쿼리문을 직접 관리해야한다는 안좋은 단점이 있다.
물론 특정 DBMS에 맞는 native Query를 직접 작성하는 이점으로 각 쿼리마다 최적화할 수 있다는 장점이 있지만 한두개정도이지 임계점이 넘어가게되면 부담이 될 수밖에 없다.
그 중에서 중복으로 사용되는 조건이나 복잡한 다이나믹 쿼리 조건이 여러 쿼리에서 동시에 사용해야될 경우 xml 쿼리 파일의 용량은 그 배수만큼 커질 것이다. (예를 들어, 페이징의 경우 where절 로직은 메인 Select 문과 count 문의 조건이 limit offset을 제외하고 동일해야한다.)
뭐 예를 들면, 아래와 같다.
다방에서 매물 목록을 조회하는 페이징 API를 호출한다면.
SELECT
*
FROM room
WHERE type = #{type}
AND deal_type = #{deal_type}
AND status = #{status}
LIMIT #{limit}
OFFSET #{offset}
위와 같은 목록쿼리가 있을 때!
아래와 같은 카운트 쿼리가 동시에 발생해야 기본적으로 페이징처리가 가능하다.
(여러 페이징 기법이 있지만 가장 기본적인 형태임 -> Postgresql 사용)
SELECT
count(*)
FROM room
WHERE type = #{type}
AND deal_type = #{deal_type}
AND status = #{status}
이때 where절 이후부터 status 조건까지의 쿼리 조각이 다른 부분에서도 활용하게 된다면 중복적으로 쿼리문이 작성되게 된다.
이런 중복 쿼리조각을 하나의 조각으로 관리할 수 있다.
<sql> 태그를 활용한 쿼리 조각화
우선 XML 문서에 아래와 같이 선언되어 있을 것이다.
<select id = "selectRooms" resultType = "room">
SELECT
*
FROM room
WHERE type = #{type}
AND deal_type = #{deal_type}
AND status = #{status}
LIMIT #{limit}
OFFSET #{offset}
</select>
<select id = "countRooms" resultType = "Integer">
SELECT
count(*)
FROM room
WHERE type = #{type}
AND deal_type = #{deal_type}
AND status = #{status}
</select>
현재는 중복된 상태이나 <sql> 태그를 이용해서 이를 관리하는 형태로 변경해보겠습니다.
<select id = "selectRooms" resultType = "room">
SELECT
*
FROM room
<include refid = "roomsCondition"/>
LIMIT #{limit}
OFFSET #{offset}
</select>
<select id = "countRooms" resultType = "Integer">
SELECT
count(*)
FROM room
<include refid = "roomsCondition"/>
</select>
<sql id = "roomsCondition">
WHERE type = #{type}
AND deal_type = #{deal_type}
AND status = #{status}
</sql>
이런식으로 쿼리문을 관리할 수 있게된다.
지금은 예제이므로 그닥 많은 차이를 느끼지는 못하겠지만 3개 이상이 되었을때는 쿼리 자체가 매우 깔끔해보이고 정리된 모습을 보여줄 수 있을 것이다.
'DB접근기술 > Mybatis' 카테고리의 다른 글
[MyBatis] <foreach> 문을 활용한 Bulk Insert (0) | 2022.08.25 |
---|---|
[Mybatis] choose절을 이용한 Dynamic SQL 구현 (choose, when, otherwise) (0) | 2021.02.02 |
[Mybatis] <if> 절을 이용한 Dynamic SQL 구현 (단일 조건) (0) | 2021.01.31 |
[Mybatis] update, insert 시 seq 반환받기. (update, insert returning) (0) | 2020.06.08 |
[Mybatis] Spring mybatis, SelectKey 태그 (0) | 2019.09.06 |