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> 구문을 사용할 수 있기 때문에 잘 활용한다면 유용한 기능이라고 생각됩니다.
< 참고 자료 >
'Programming > Spring' 카테고리의 다른 글
Logback PatternLayout을 통한 로그 마스킹 처리 방법 (1) | 2024.11.02 |
---|---|
(spring project) log4j2 로그 파일 분리하기 (1) | 2024.08.25 |
MyBatis SQL Injection 발생하는 상황 및 방어 방법 (0) | 2024.04.10 |
spring + oracle(ojdbc) 연결 방법 정리 (0) | 2024.03.30 |
mybatis selectKey 사용 방법 및 주의할 점 (selectKey 다중 컬럼) (0) | 2024.03.20 |