[Spring] mybatis의 동적 쿼리

류넹·2024년 2월 28일
1

Spring

목록 보기
17/50

# 목적

  • mybatis의 동적 쿼리 정리




🔎 mybatis의 동적 쿼리

  • mybatis는 <if>, <choose> ~ <when> ~ <otherwise>, <where>, <set>, <foreach>
    태그를 사용해서 동적 SQL을 작성할 수 있다.

  • mybatis에서 동적 SQL 작성을 지원하기 위해서 제공하는 태그는 JSTL의 태그와 사용법이 매우 비슷하다.




1. <if> 태그

- 형식

<if test="조건식">
	SQL 구문
</if>
<!-- 
	* 제시된 조건식은 true/false로 판정되는 조건식이다.
	* 제시된 조건식이 true로 판정되면 태그 내부의 SQL 구문이 사용된다.
-->

- 예시

  • 매퍼 인터페이스의 추상메서드
List<Book> getBooks(Criteria criteria)
  • 매퍼 파일
<select id="getBooks" parameterType="dto.Criteria" resultType="vo.Book">
	select
		*
	from
		books
	where
		book_status = 'SELL'
		<if test="title != null">
			book+title = #{title}
		</if>
	</select>



2. <choose> ~ <when> ~ <otherwise>

- 형식

<choose>
	<when test="조건식1">
        SQL 구문1
    </when>
  	<when test="조건식2">
        SQL 구문2
    </when>
  	<when test="조건식3">
        SQL 구문3
    </when>
  	<otherwise>
        SQL 구문4
    </otherwise>
</choose>
<!-- 
	 * 제시된 여러 조건 중에서 조건식이 true로 판정되는 SQL 구문이 사용되고,
	   제시된 모든 조건식이 false로 판정되면 otherwise의 SQL 구문이 사용된다.
	 * <otherwise>는 생략 가능
-->

- 예시

<select id="getBooks" parameterType="dto.Criteria" resultType="vo.Book">
    select
  		*
    from
  		books
    where
  		book_status = 'SELL'
  		<choose>
          	<when test="title != null">
              	and book_title = #{title}
            </when>
          	<when test="author != null">
              	and book_author = #{author}
            </when>
          	<when test="publisher != null">
              	and book_publisher = #{publisher}
            </when>
  		</choose>
</select>



3. <where>

- 형식

<where>
  	<!-- 동적 SQL 구문 -->
    <if test="조건식">
        SQL 구문
    </if>
</where>
<!--
	* <where> 태그는 반드시 <if>, <choose> ~ <when> ~ <otherwise>, <foreach> 태그를 
      사용하는 동적 SQL 구문이 위치해야 한다.
	* <where> 태그는 2가지 동작을 처리한다.
		1. where 키워드 추가
			ex)
				<select>
					select
						*
					from
						books
					where
						book_status = 'SELL'
						<if test="title != null">
							and book_title = #{title}
      					</if>
    			</select>
				=====> 1) 위 경우에는 <where>태그를 사용할 필요가 없다.
				<select>
					select
						*
					from
						books
					where
						<if test="title != null">
							and book_title = #{title}
      					</if>
    			</select>
				=====> 2) 위 경우에 title 값이 null이면 실행되는 SQL은 아래와 같다.
					select
						*
					from
						books
					where
				=====> 3) 위의 SQL은 where절이 비어있어서 오류가 발생하기 때문에
					   아래와 같이 <where> 태그를 이용해서 작성해야 한다.
				<select>
					select
						*
					from
						books
					<where>
						<if test="title != null">
							and book_title = #{title}
      					</if>
					</where>
    			</select>

		2. and 키워드 제거
			ex)
				<select>
					select
						*
					from
						books
					where
						<if test="title != null">
							and book_title = #{title}
      					</if>
						<if test="author != null">
							and book_author = #{author}
      					</if>
						<if test="publisher != null">
							and book_publisher = #{publisher}
      					</if>
    			</select>
				=====> 위 경우에 title이 null이고 author나 publisher가 null이 아니면
					   아래와 같은 SQL 구문이 실행되고, where 다음에 and가 있어서 오류가 발생한다.
							select
								*
							from
								books
							where
								and book_author = ?
				=====> 아래처럼 <where> 태그를 사용하면 and가 자동으로 제거된다.
							select
								*
							from
								books
							<where>
								and book_author = #{author}
							</where>
-->



4. <set>

- 형식

<set>
  	동적 SQL 구문
</set>
<!-- 
	* <set> 태그는 동적으로 SET 키워드를 추가하고, 필요없는 콤마(,)를 제거한다. 
-->

- 예시

<update>
  	update books
  	set
      	<if test="title != null">
          	book_title = #{title},
      	</if>
      	<if test="price != 0">
          	book_price = #{price},
      	</if>
      	<if test="filename != null">
          	book_filename = #{filename},
      	</if>
  	where
  		book_no = #{no}
</update>
<!-- 
	1) 위의 경우 title, price에는 값이 있고, filename에 값이 null 이면
       아래와 같은 SQL 구문이 실행되고, 맨 마지막에 ','가 있어서 오류가 발생한다.
			update books
			set
				book_title = #{title},
				book_price = #{price},
			where
				book_no = #{no}
-->

<update>
  	update books
  	<set>
      	<if test="title != null">
          	book_title = #{title},
      	</if>
      	<if test="price != 0">
          	book_price = #{price},
      	</if>
      	<if test="filename != null">
          	book_filename = #{filename},
      	</if>
    </set>
  	where
  		book_no = #{no}
</update>
<!-- 
	2) 위의 경우 title, price에는 값이 있고, filename에 값이 null 이면
       아래와 같은 SQL 구문이 실행되고, 맨 마지막에 위치한 ','가 제거된다.
			update books
			set
				book_title = #{title},
				book_price = #{price}
			where
				book_no = #{no}
-->



5. <foreach>

- 형식

<foreach item="num" index="index" collection="productNumbers"
         open="(" separator="," close=")">
  	#{num}
</foreach>
<!-- 
	* 콜렉션에 대한 반복처리를 지원하는 태그
 	* in 연산자와 주로 사용된다.
-->

- 주요 속성

  1. item
    • collection에서 지정된 배열 혹은 List에서 순서대로 하나씩 추출되는 값을 담을 변수명을 지정한다.
  1. index
    • collection에서 지정된 배열 혹은 List를 반복처리할 때마다 0부터 시작하는 인덱스 값을 담을 변수명을 지정한다.
      정의만 하고 sql 구문에서는 사용하지 않는다.
  1. collection
    • 반복대상이 되는 값을 담고 있는 프로퍼티명 혹은 파라미터명을 지정한다.
  1. open
    • <foreach> 태그로 반복을 시작하기 전에 sql 구문에 출력할 컨텐츠를 지정한다.
  1. close
    • <foreach> 태그로 반복이 종료되었을 때 sql 구문에 출력할 컨텐츠를 지정한다.
  1. separator
    • #{num}으로 값을 하나씩 출력할 때마다 각각의 값을 구분하는 구분문자를 지정한다.

- 예시

  • 매퍼 인터페이스의 추상메서드
public interface BookMapper {
	void deleteBooks(@Param("bookNumbers") List<Integer> bookNumbers);
}
  • 매퍼 파일
<delete>
  	delete from books
  	where
  		book_no in
  		<foreach index="index" item="value" collection="bookNumbers"
                 open="(" separator="," close=")">
          	#{value}
        </foreach>
</delete>
<!-- 
	* bookNumbers로 찾은 값 : List<Integer>, 정수값을 여러개 담고 있는 List 객체를 전달받는다.
	* 위의 SQL 구문이 실행되면 아래와 같은 SQL이 실행된다.
		delete from books
		where
			book_no in
			(100, 102, 104)
-->

- 참고 이미지

profile
학습용 커스터마이징 간단 개발자 사전

0개의 댓글