- MyBatis 동적 SQL
- 동적 SQL의 구문을 이해한다.
- if, choose, trim, foreach를 사용하여 동적 SQL을 작성 할 수 있다.
검색조건에 따라 검색해야 하는 SQL문이 달라지기 때문에 이를 처리하기 위해서 동적 SQL이 사용됨
이 기능이 없으면, 각 조건에 따른 if문이 필요하기 때문에 Dynamic SQL 덕분에 소스코드가 간결해집니다. 모든 동적 SQL 처리를 xml파일에서 할 수 있다는 장점이 있습니다.
- if
- trim(where, set)
- choose(when, otherwise)
- foreach
- MyBatis 구문을 이용하여 SQL문이 실행 시에 변경되기 때문에 모든 케이스에 대해 테스트가 이루어져야 함
- 동적 SQL문이 없는 상태에서 정상적인 실행을 확인 후, 동적 SQL을 추가해서 개발
- MyBatis에서 가장 공통적으로 사용되는 요소
<select id="findActiveBlogWithTtileLike" resultType="Blog"> select * from blog where state='ACTIVE' <if test="title != null"> and title like #{title} </if> </select>
- 위 구문은 파라미터 중 title에 값이 존재할 경우 and title like ${title} 구문을 본 쿼리문에 포함시킨다.
<select id="findActiveBlogLike" resultType="Blog"> select * from blog where state='ACTIVE' <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>
- 위 구문은 author와 author.name 파라미터에 값이 존재할 경우 AND author_name like ${author.name} 구문을 본 쿼리문에 포함시킨다.
- 파라미터 타입 안에 다른 타입(클래스)이 포함되어 캡슐화를 이룰 경우 ".(점)" 연산자로 접근할 수 있다.
if문 예시입니다.
if 태그 내 test 속성 값이 참일 때
if 태그 안 내용 "AND title like ${title}" 구문이 같이 실행됩니다.
만약 if문이 없었다면 별도의 두 개의 sql문이 필요했을 겁니다..
- 여러 구문 중 하나만 실행
<select id="findActiveBlogLike" resultType="Blog"> select * from blog where state='ACTIVE' <choose> <when test="title != null"> AND title like #{title} </when> <when test="author != null and author.name != null"> AND author_name like #{author.name} </when> <otherwise> AND featured = -1 </otherwise> </choose> </select>
- title 파라미터의 값이 존재하면 AND title like #{title} 구문을 포함
- author와 author.name 파라미터 값이 존재하면 AND author_name like #{author.name} 구문을 포함.
- 둘 다 존재하지 않다면 AND featured = -1 구문을 포함.
- 여러 구문 중 하나만 실행한다
↓ 틀린 예시<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>
- 만약 아무런 파라미터도 없다면 아래와 같은 쿼리가 만들어짐
select * from blog where
- 두 번째 조건만 해당된다면 아래와 같은 쿼리가 만들어짐
select * from blog where AND title like #{title}
- 모두 실행할 수 없는 쿼리가 만들어짐
- 때문에 trim을 사용해야 함
<select id="findActiveBlogLike" resultType="Blog"> select * from blog <where> <if test="state != null"> state = ${state} </if> <if test="title != null"> AND title = #{title} </if> <if test="author != null and author.name != null"> AND author_name like #{author.name} </if> </where> </select>
마지막 소스코드의 경우, 모든 if문이 false면 "select * from blog"가 쿼리문이 됩니다. 발생할 수 있는 에러 하나를 방지했습니다.
하지만 두 번째 if문 or 세 번째 if문만 true인 경우, 또 구문 오류가 발생합니다..
- < where> < /where>는 내부에 컨텐츠가 존재할 때 where 키워드를 포함시킴
- 그렇지 않을 경우는 where 키워드를 쓰지 않음
- 또한, where 다음 and 혹은 or가 바로 올 경우 and, or 키워드를 삭제시킴
<trim prefix="WHERE" prefixOverrides="AND | OR"> ... </trim>
- 혹은, 위 구문과 같이 trim을 바로 사용할 수도 있다.
<select id="findActiveBlogLike" resultType="Blog"> select * from blog <trim prefix="WHERE" prefixOverrides="AND"> <if test="state != null"> state = ${state} </if> <if test="title != null"> title = #{title} </if> <if test="author != null and author.name != null"> author_name like #{author.name} </if> </trim> </select>
trim 태그 내 if문 중 하나라도 참이면, where 절을 붙여서 SQL문을 만들어줍니다. if문이 두 개 이상 참이면, AND 구문을 추가해줍니다.
- trim은 where절 뿐만 아니라 set 절에도 적용 가능하다.
- < set>< /set>는 내부에 컨텐츠가 존재할 때 set 키워드를 포함시킴
- 그렇지 않을 경우는 set 키워드를 쓰지 않음
- 또한, set 다음 ",(콤마)"가 바로 올 경우 ",(콤마)"를 삭제시킴
<update id="updateAuthorNecessary"> update Author <trim prefix="set" overrides=","> <if test="state != null"> state = #{state} </if> <if test="title != null"> title = #{title} </if> <if test="author != null and author.name != null"> author_name = #{author.name} </if> </trim> where author_id = #{id} </update>
- Dynamic Query에서 공통적으로 필요한 기능은 Collection 의 반복 처리 기능
- in 키워드를 사용할 때 종종 사용됨
<select id="selectPostIn" resultType="domain.blog.Post"> select * from POST P where id in <foreach item="item" index="index" collection="list" open="(" separator="," close=")"> #{item} </foreach> </select>
- collection 속성은 List일 경우는 list, array가 사용된다.
- 파라미터가 List일 경우 "list"
- 파라미터가 Array(배열)일 경우 "array"를 사용한다.