본문 바로가기

Backend/DB 실무

[Mybatis] WHERE을 조금 더 편하게 사용하기

반응형

물론 여기에 나오는 것은 도움을 주는것이지 쿼리를 작성하는데 필수적인 부분은 아님

하지만 좀 더 간결하고 깔끔하게 작성하는데 도움이 될 수 있다. 

 

아래와 같이 쿼리를 작성하면 에러가 발생한다.

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

 

 

만약 WHERE절에 아무런 조건이 붙어 있지 않은 경우 아래와 같이 쿼리가 동작하니 FAIL

SELECT * FROM BLOG
WHERE

 

만약 WHERE절에서 'WHERE AND'와 같은 구문이 만들어지는 경우 아래와 같이 쿼리가 동작하니 FAIL

SELECT * FROM BLOG
WHERE
AND title like ‘someTitle’

 

이러한 경우를 방지하기 위해서 trim, where, set 표현을 사용

1. where

=> 쿼리문에 where절을 묶어서 사용

<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>
  </where>
</select>

 

이렇게만 작성한다면 아래와 같은 에러가 발생할 수 있음

  SELECT * FROM BLOG
  WHERE
        AND title like #{title}

2. set

=> Update시 Set에 들어갈 부분을 조건에 따라 주고 싶을 때 사용

<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>
  where id=#{id}
</update>

하지만 위와 같이 작성하면 마지막에 ,가 남게 된다.

3. trim

=> 문자열을 기본으로 추가하거나 Override하는 역할 수행

 

먼저 where에서 본 문제점을 해결하는 부분

아래의 경우 prefix로 where를 기본으로 붙여주고,
prefixOverrides로 되어있는 "AND | OR"가 나오면 해당 문자열을 지움

<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG
    <trim prefix="WHERE" prefixOverrides="AND |OR ">
      <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>
    </trim>
</select>

 

 

set에서 본 문제점을 해결하는 부분

아래의 경우 prefix로 set를 기본으로 붙여주고,
suffixOverrides로 되어있는 ","가 맨 끝에 나오면 해당 문자열을 지움

<update id="updateAuthorIfNecessary">
  update Author
    <trim prefix="set" suffixOverrides=",">
      <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>
    </trim>
  where id=#{id}
</update>

 

+ ) ","를 맨 앞에 붙여서 사용하는 경우
prefix로 set를 붙여주고, prefixOverrides로 되어있는 ","가 맨 앞에 나오면 해당 문자열을 지움

<update id="updateAuthorIfNecessary">
  update Author
    <trim prefix="set" prefixOverrides=",">
      <if test="userId != null">userId=#{userId}</if>
      <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>
    </trim>
  where id=#{id}
</update>

 

++)

<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG
  WHERE
  <if test="state != null">
    state = #{state}
  </if>
  <trim prefix="AND (" prefixOverrides="AND | OR" suffix=")">
    <if test="title != null">
      OR title like #{title}
    </if>
    <if test="author != null and author.name != null">
      OR author_name like #{author.name}
    </if>
    <if test="category != null and category != null">
      OR category like #{category}
    </if>
  </trim>
</select>

= 맨 앞에 "AND (" 를 붙이고 trim 내부 문의 맨 앞에 "AND" 또는 "OR"가 있으면 제거,
맨 끝에 ")" 추가

 

trim문법 정리

prefix trim문에서 작성하는 쿼리의 맨 앞에 해당 문자를 추가
prefixOverrides trim문에서 작성하는 쿼리의 맨 앞에 오는 문자들을 삭제
suffixOverrides trim문에서 작성하는 쿼리의 맨 끝에 오는 문자들을 삭제
suffix trim문에서 작성하는 쿼리의 맨 끝에 해당 문자를 추가

 

반응형

'Backend > DB 실무' 카테고리의 다른 글

[SQL] SELECT한 결과 Insert 혹은 Update  (0) 2024.02.28
[Mybatis] 반복문 및 bind  (0) 2024.02.26
[Mybatis] 조건문  (0) 2024.02.26
[H2] H2 SQL파일 로드  (0) 2024.02.26
[Mybatis] Mybatis VS JPA  (0) 2024.02.20