본문 바로가기
SQL

Mybatis와 Mybatis의 동적쿼리

by 유서담 2024. 2. 29.

Mybatis

 

= Mybatis는 자바 언어로 작성된 오픈 소스 SQL 매핑 프레임워크다. SQL 문장과 자바 객체 사이의 매핑 작업을 처리하는데 사용되며, 이를 통해 데이터베이스와의 상호작용을 더욱 효율적으로 수행할 수 있다

 

 

Mybatis의 특징

  • SQL 쿼리를 XML 파일이나 Annotaion에 작성하므로 SQL과 자바 코드를 분리하여 가독성을 높이고 유지 보수를 용이하게 한다
  • JDBC 코드의 보잡성을 추상화 한다
  • SQL 쿼리 실행 결과를 자바 객체에 매핑하여 처리하는 작업을 간단화 한다

 

 

Mybatis 동적쿼리

 

<if> 태그

<if>태그는 주어진 조건식이 참(true)일 때 내부의 SQL 구문을 사용한다. 조건식은 무조건 true나 false로 판정이 되어야 한다

 

형식

<if test="조건식">
  SQL 구문
</if>

 

예시

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

 

예시에서 getBooks() 메소드가 호출될 때, title 파라미터가 null이 아니라면 

book_title = #{title}이라는 조건이 SQL 쿼리에 추가된다

 

 

 

<choose>, <when>, <otherwise> 태그

<choose>태그는 여러 조건 중 하나를 선택하여 SQL 구문을 사용하게 해주는 태그.

내부의 <when> 태그로 조건을 설정하며, 모든 조건이 거짓(false)일 때 사용할 <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>

 

 

예시

<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>

 

예시에서는 title, author, publisher 세 가지 조건 중 하나가 참일 때 해당 SQL 구문이 쿼리에 추가되는 예시이다

 

 

 

<where>태그

<where>태그 내부에는 <if>, <choose> ~ <when> ~ <otherwise>, <foreach> 태그를 사용하는 동적 SQL 구문이 위치해야 한다

 

형식

<where>
  동적 SQL 구문
</where>

 

 

where 키워드 추가

<select>
  select *
  from books
  <if test="title != null">
    and book_title = #{title}
  </if>
</select>

 

<where>태그는 조건에 따라 where 키워드를 SQL 쿼리에 추가하는 기능을 수행한다.

예를 들어, 위의 SQL 쿼리에서 title 값이 null이 아니면 where 키워드가 추가되지 않는다

 

<select>
  select *
  from books
  <where>
    <if test="title != null">
      and book_title = #{title}
    </if>
  </where>
</select>

 

그러나 같은 쿼리에 <where> 태그를 사용하면, title 값이 null일 때도 where 키워드가 추가된다

 

 

and 키워드 제거

 

<select>
  select 
    *
  from 
    books
  where
  <if test="title != null">
    book_title = #{title}
  </if>
  <if test="author != null">
    and book_author = #{author}
  </if>
  <if test="publisher != null">
    and book_publisher = #{publisher}
  </if>
</select>

 

<where> 태그는 where 키워드 바로 뒤에 오는 and 키워드를 제거하는 기능을 수행한다.

예를 들어, 위의 SQL 쿼리에서 title이 null이 아니고, author나 publisher가 null이 아니라면 where 바로 뒤에 and가 오는 오류가 발생한다

 

<select>
  select 
    *
  from 
    books
  <where>
    <if test="title != null">
      book_title = #{title}
    </if>
    <if test="author != null">
      and book_author = #{author}
    </if>
    <if test="publisher != null">
      and book_publisher = #{publisher}
    </if>
  </where>
</select>

 

그러나 같은 쿼리에 <where> 태그를 사용하면, where 바로 뒤에 오는 and 키워드가 제거가 된다

 

 

 

<set> 태그

<set>태그는 쿼리에서 동적으로 SET 키워드를 추가하고, 필요없는 콤마(,)를 제거하는 역할을 수행한다

 

-예시

<update>
	update books
	<set>
		<if test="title != null">
		book_title = #{title}
		</if>
		<if test="author != null">
		book_author = #{author}
		</if>
		<if test="price != 0">
		book_price = #{price}
		</if>
		<if test="filename != null">
		book_filename = #{filename}
		</if>
	</set>
	where book_no = #{no}
</update>

 

이 쿼리에서 title, author, price, filename에 대한 값이 있을 경우에만 해당 필드를 업데이트한다.

만약 filename에 값이 null일 경우, 이 필드는 업데이트 대상에서 제외되며, 생성되는 SQL 구문에서 불필요한 콤마(,)를 제거한다

 

update books
set
	book_title = #{title},
	book_author = #{author},
	book_price = #{price}
where
	book_no = #{no}

 

그리고 <set>태그는 SQL 구문에 SET 키워드를 동적으로 추가해준다.

 

 

 

<forEach>태그

<forEach>태그는 SQL 쿼리에서 반복 처리를 지원하는 태그다. 이 태그는 주로 'in' 연산자와 함께 사용되며, 콜렉션에 대한 반복 처리를 수행할 수 있다.

 

 

- <forEach>태그의 속성

<foreach item="num" index="index" collection="productNumbers" open="(" separator="," close=")" nullable="true">
	#{num}
</foreach>

 

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

 

-  예시

public interface BookMapper {
	void deleteBooks(@Param("bookNumbers")List<Integer> bookNumbers);
}

<delete id="deleteBooks">
	delete from books
	where book_no in
	<foreach index="index" item="value" collection="bookNumbers" open="(" separator="," close=")">
		#{value}
	</foreach>
</delete>

 

 

'bookNumber'는 List<Integer> 형태를 가지며, 여러 개의 정수 값을 담고 있는 List 객체를 전달받는다

이 SQL 구문을 실행하면 이러한 SQL이 생성된다

 

delete from books
where
	book_no in
	(100, 102, 104)