Programming/Spring

(MyBatis) include refid 용도 및 사용 방법

Jan92 2024. 12. 14. 21:29
반응형

MyBatis <include refid> 용도 및 사용 방법

mybatis include refid

구축된 시스템을 분석하는 과정에서 mybatis xml 파일 내부적으로 <include refid="someSql"></include>, <sql id="someSql"></sql> 형식의 태그가 사용되는 것을 보았는데요.

해당 포스팅에서는 include 태그와 sql 태그는 어떤 용도로 사용되는지, 어떻게 사용되는지에 대해 정리하였습니다.

 


<include>, <sql> 태그의 사용 용도

<!-- 다른 구문에서 재사용 가능한 SQL 구문 -->
<sql id="whereEmpNo">
    WHERE emp_no = #{empNo}
</sql>

<!-- include 태그를 통해 sql 태그 내의 쿼리를 가져와서 사용하는 구문1 -->
<select id="getEmployeeInfo" resultType="map">
    SELECT emp_no
         , first_name
         , last_name
      FROM employees
    <include refid="whereEmpNo"></include>
</select>

<!-- include 태그를 통해 sql 태그 내의 쿼리를 가져와서 사용하는 구문2 -->
<select id="getDeptEmpInfo" resultType="map">
    SELECT emp_no
         , dept_no
      FROM dept_emp
    <include refid="whereEmpNo"></include>
</select>

(하나의 SQL Map XML 파일에 정의된 쿼리)

 

위 예시를 통해 알 수 있는 것처럼 include, sql 태그는 여러 쿼리에서 반복 사용되는 sql 구문을 <sql> 태그로 따로 분리해서 정의하고, 실제 사용되는 쿼리 내에서 <include> 태그를 통해 가져옴으로써 반복되는 sql 구문을 줄이고, 관리와 유지보수를 쉽게 하는 데 용도가 있습니다.

 

 

<sql id="sql구문의id값">
    ...
</sql>

<sql> 태그는 쿼리에서 재사용 가능한 sql 구문을 정의할 때 사용되며, id 속성 값을 통해 판별합니다.

 

 

<include refid="정의된sql구문의id값"></include>

<include> 태그에서는 refid 속성에 사용할 sql 구문의 id 값을 명시하여 정의된 sql 구문을 사용할 수 있습니다.

 

 

* 다른 블로그에서 <sql> 태그가 쿼리의 상단에 정의되어 있어야 사용할 수 있다는 내용을 보았는데, 버전의 차이인지 mybatis 3.5.4 버전, mybatis-spring 2.0.4 버전 기준으로는 <sql> 태그가 정의된 위치에 상관없이 사용할 수 있었습니다.

 

 


몇 가지 사용 예시

1. 조회할 컬럼에 대해 재사용 가능한 sql 구문을 만드는 경우

<!-- 조회할 컬럼에 대한 sql 구문 -->
<sql id="selectColumns">
    ${alias}.emp_no,
    ${alias}.first_name,
    ${alias}.last_name
</sql>

<!-- 조회 구문 -->
<select id="selectEmpInfo" resultType="map">
    SELECT
        <include refid="selectColumns"><property name="alias" value="t1"></property></include>,
        <include refid="selectColumns"><property name="alias" value="t2"></property></include>
      FROM employees_1 AS t1
      JOIN employees_2 AS t2
        ON t1.emp_no = t2.emp_no
     WHERE t1.emp_no = #{empNo}     
</select>

첫 번째 예시는 조회할 컬럼에 대해 재사용 가능한 sql 구문을 만드는 경우입니다.

이때 주의할 점은 'alias' 처럼 <property> 태그를 통해 <sql> 태그에 값을 넘겨주는 경우 <sql> 태그 내에서 '#'이 아닌 '$'를 써서 값을 받아야 한다는 점입니다.

 

* 사용 용도 부분의 내용에서 보았던 where sql 구문처럼 property 태그를 통해 넘어오는 것이 아니라 쿼리를 호출하는 외부에서 파라미터를 통해 넘어오는 값은 '#'를 사용하여 받을 수 있습니다.

 

 

 

2. 검색 조건으로 사용하기

<!-- 게시판 등에서 다음과 같은 검색 조건이 동일하게 사용되는 경우 -->
<sql id="searchBoard">
    <if test="searchType != null">
        <if test="searchType == 'title'">AND title LIKE CONCAT('%', #{keyword}, '%')</if>
        <if test="searchType == 'content'">AND content LIKE CONCAT('%', #{keyword}, '%')</if>
    </if>
</sql>

<select id="selectBoardInfo" resultType="map">
    SELECT title
        , content
      FROM board   
     WHERE 1=1
    <include refid="searchBoard"></include>
</select>

두 번째 예시는 게시판 등 여러 개의 조회 쿼리에서 같은 검색 조건이 사용되는 경우, 위 예시와 같이 검색 조건을 sql 구문으로 빼고 실제 조회 쿼리에서 include 태그로 가져와서 사용하는 방법도 있습니다.

 

 

 

3. WITH 절을 sql 구문으로 사용하기

<!-- 반복 사용되는 WITH 절을 sql 구문으로 정의 -->
<sql id="withSalaries">
    WITH sal AS (
                 SELECT emp_no
                      , salary
                   FROM salaries
                  WHERE salary > #{salary} 
                )
</sql>

<select id="selectEmpWithSalaries" resultType="map">
    <include refid="withSalaries"></include>
    SELECT e.emp_no
         , e.birth_date
         , s.salary
      FROM employees e
      JOIN sal s ON e.emp_no = s.emp_no
</select>

(WITH 절의 사용 예시가 적절하지 않을 수 있지만 단순 사용 방법의 예시로 봐주시면 됩니다.)

 

다음 예시로는 반복 사용되는 WITH 절을 sql 구문으로 정의하여 여러 쿼리에서 사용할 수도 있습니다.

 

 

* 위 예시들에서는 SELECT 절에서 사용하는 방식만 소개했지만 insert, update, delete 쿼리에서도 <include>, <sql> 구문을 사용할 수 있기 때문에 잘 활용한다면 유용한 기능이라고 생각됩니다.

 

 

 

 

< 참고 자료 >

https://mybatis.org/mybatis-3/ko/sqlmap-xml.html

반응형