검색 또는 업데이트 조건을 동적으로 받는 경우 자주 사용하는 MyBatis 문법에 대해 정리해보고자 한다.
1. <where>
- <if> 태그만 사용할 때는 각각의 조건들만 동적으로 추가 가능했지만, <where> 태그를 사용하게 되면 <where> 태그 하위의 <if> 태그 리턴 값에 따라 조건문 자체를 동적으로 active 시킬 수 있다.
- 하위의 <if> 태그 값을 모두 충족하지 않으면 WHERE가 생기지 않고 SQL 종결되며, 하나라도 충족하면 SQL에 WHERE가 붙는다.
- 하위 <if> 태그에는 AND || OR 모두 받을 수가 있다.
- 불필요한 AND 또는 OR 구문을 제거해준다.
1) <where> 태그 사용하지 않을 때
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE <if test="state != null"> state = #{state} </if> <if test="title != null"> AND title like #{title} </if> <if test="author != null and author.name != null"> AND author_name like #{author.name} </if> </select> | cs |
<if> 안의 모든 조건이 충족하지 않는 경우 위의 구문은 아래과 같이 오류를 발생시킨다.
1 2 3 | SELECT * FROM BLOG WHERE | cs |
2) <where> 태그를 사용하면
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG <where> <if test="state != null"> AND state = #{state} </if> <if test="title != null"> AND title like #{title} </if> <if test="author != null and author.name != null"> AND author_name like #{author.name} </if> </where> </select> | cs |
<if> 안의 모든 조건이 충족하지 않으면 구문이 아래와 같이 정상적으로 끝나게 된다.
1 2 | SELECT * FROM BLOG | cs |
마찬가지로 AND 조건 뿐만 아니라 OR 조건도 받을 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | SELECT DISTINCT PURDOC_NO FROM PU_PURORDERACCT_DTL <where> <if test="P_FROM_CC != null and P_FROM_CC != ''"> OR CC_CD BETWEEN #{P_FROM_CC} AND #{P_TO_CC} </if> <if test="P_WBS_NO != null and P_WBS_NO != ''"> OR WBS_NO BETWEEN #{P_WBS_NO} AND #{P_WBS_NO_TO} </if> <if test="P_FROM_PM_ORD != null and P_FROM_PM_ORD != ''"> OR PM_ORD_NO BETWEEN #{P_FROM_PM_ORD} AND #{P_TO_PM_ORD} </if> <if test="P_ASSET_CD != null and P_ASSET_CD != ''"> OR ASSET_CD BETWEEN #{P_ASSET_CD} AND #{P_ASSET_CD_TO} </if> </where> | cs |
2. <set>
- <set> 태그도 <where> 태그와 마찬가지로 <set> 태그 하위의 <if> 태그 리턴 값에 따라 SET 구문을 동적으로 active 시킨다.
- 조건 뒤에 불필요한 쉼표(,) 를 제거해준다.
1 2 3 4 5 6 7 8 9 10 | <update id="updateAuthorIfNecessary"> update Author <set> <if test="username != null">username=#{username},</if> <if test="password != null">password=#{password},</if> <if test="email != null">email=#{email},</if> <if test="bio != null">bio=#{bio},</if> </set> </update> | cs |
3. <trim>
- prefix : 실행될 구문의 맨 앞에 문자열을 추가
- prefixOverrides : 실행될 구문의 맨 앞에 문자열이 존재한다면 제거
- suffix : 실행될 구문의 맨 뒤에 문자열을 추가
- suffixOverrides : 실행될 구문의 맨 뒤에 문자열이 존재한다면 제거
- 위의 속성들을 활용하여 보다 복잡한 조건문을 동적으로 처리할 수 있다.
예시 1) 여러 개의 검색 조건 중 OR 검색을 해야할 때 prefixOverrides 속성을 사용해 AND 다음 OR 이 올 경우 바로 삭제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <if test="!P_SEARCH_TEXT_1.equals('%%'.toString())"> <trim prefix="AND (" prefixOverrides="OR" suffix=")"> <![CDATA[OR A.TLMKT_YY like #{P_TLMKT_YY_TEXT} AND A.TLMKT_SQ_SQ like #{P_SEARCH_TEXT_1}]]> </trim> </if> <if test="!P_SEARCH_TEXT_2.equals('%%'.toString())"> <trim prefix="AND (" prefixOverrides="OR" suffix=")"> <![CDATA[OR D.KOR_NM like #{P_SEARCH_TEXT_2}]]> </trim> </if> <if test="!P_SEARCH_TEXT_3.equals('%%'.toString())"> <trim prefix="AND (" prefixOverrides="OR" suffix=")"> <![CDATA[OR C.DEPT_NM like #{P_SEARCH_TEXT_3}]]> </trim> </if> | cs |
예시 2) index가 1000개 이상일 때마다 IN절을 새로 생성하고, 미만이면 suffixOverrides 속성을 사용해 IN절 구문 삭제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <if test="P_PJT_NO != null"> AND ( A.PJT_NO IN <trim suffixOverrides = " OR A.PJT_NO IN ()"> <foreach collection="P_PJT_NO" index="index" item="item" open="(" close=")"> <if test = "index != 0"> <choose> <when test = "index % 1000 == 999">) OR A.PJT_NO IN (</when> <otherwise>,</otherwise> </choose> </if> #{item} </foreach> </trim> ) </if> | cs |
출처 : MyBatis Dynamic SQL Document
https://mybatis.org/mybatis-3/dynamic-sql.html#trim-where-set
'Programming > Java * Spring' 카테고리의 다른 글
[SpringBoot] JWT(Json Web Token) 활용한 인증 처리 (0) | 2023.04.15 |
---|---|
[Spring] 하나의 requestMapping으로 여러개의 request 받기 (2) | 2019.12.20 |
[SpringBoot] No embedded stylesheet instruction for file 해결 방법 (out.xml 파일이 자동으로 생성되면서 서버가 켜지지 않음) (0) | 2019.11.18 |
[Spring Boot] Authorization Server(feat. Postman) (0) | 2019.07.10 |
MyBatis 사용 목적, 셋팅, Log4j(로그 출력) (0) | 2019.06.13 |