본문 바로가기

DevOps/MyBatis

[Mybatis] WHERE 1= 1 사용 대신 trim으로 해결하기 - 컴도리돌이

728x90
728x90

MyBatis에서 동적 SQL을 작성할 때 흔히 WHERE 1=1 패턴을 사용하는 경우가 많아요. 여러 조건을 동적으로 추가해야 할 때 처음부터 WHERE 절을 넣어두고, 뒤에 AND 또는 OR 조건을 추가하는 방식이죠. 하지만 이 방식은 SQL 가독성을 해치고, 불필요한 연산이 발생할 가능성이 있어요. 이를 해결하기 위해 MyBatis에서는 <trim> 태그를 제공하며, 이를 활용하면 불필요한 AND 또는 OR을 자동으로 제거하면서도 깔끔한 SQL을 생성할 수 있어요.

1. WHERE 절에서 trim 활용하기

기본적으로 <trim> 태그는 prefix, suffix, prefixOverrides, suffixOverrides 속성을 사용하여 특정 키워드를 동적으로 추가하거나 제거하는 기능을 제공해요. 예를 들어, 아래 코드처럼 prefix="WHERE" prefixOverrides="AND |OR" 설정을 하면, 동적으로 추가된 AND 또는 OR 키워드가 자동으로 제거돼요.

<select id="findUsers" resultType="com.example.User">
    SELECT * FROM users
    <trim prefix="WHERE" prefixOverrides="AND |OR ">
        <if test="name != null">
            AND name = #{name}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
        <if test="email != null">
            OR email = #{email}
        </if>
    </trim>
</select>
  • name = 'John'과 email = 'john@example.com'이 입력되었을 때:
SELECT * FROM users WHERE name = 'John' OR email = 'john@example.com'
  • name = 'John', age = 30, email = 'john@example.com'이 입력되었을 때:
SELECT * FROM users WHERE name = 'John' AND age = 30 OR email = 'john@example.com'

 

이처럼 <trim>을 활용하면 WHERE 1=1을 사용하지 않아도 자연스럽게 조건문이 정리되며, 불필요한 AND 또는 OR 키워드를 제거할 수 있어 SQL의 가독성이 좋아져요.


2. UPDATE 문에서 trim 활용하기

MyBatis에서는 <set> 태그를 사용하면 자동으로 마지막 콤마를 제거해 주지만, <trim>을 직접 사용하면 더욱 세밀한 제어가 가능해요. 아래와 같이 <trim>을 활용하여 SET 절을 동적으로 구성할 수 있어요.

<update id="updateUser">
    UPDATE users
    <set>
        <if test="name != null">
            name = #{name},
        </if>
        <if test="age != null">
            age = #{age},
        </if>
        <if test="email != null">
            email = #{email}
        </if>
    </set>
    WHERE id = #{id}
</update>
  • name = 'John', email = 'john@example.com'만 입력되었을 때:
UPDATE users SET name = 'John', email = 'john@example.com' WHERE id = 1
  • age = 30만 입력되었을 때:
UPDATE users SET age = 30 WHERE id = 1

 

위 코드에서는 <trim prefix="SET" suffixOverrides=", " > 설정을 통해 마지막에 남을 수 있는 ,를 자동으로 제거하도록 했어요. 실제로 <set> 태그도 내부적으로 동일한 역할을 수행하지만, <trim>을 사용하면 보다 다양한 상황에서 활용할 수 있다는 장점이 있어요.


3. IN 절에서 trim과 foreach 함께 활용하기

특정 ID 목록을 조회하는 경우 IN 절을 동적으로 구성해야 하는 상황이 발생하는데, 이때 <trim><foreach>를 함께 사용하면 더욱 깔끔한 SQL을 만들 수 있어요.

<select id="findUsersByIds" resultType="com.example.User">
    SELECT * FROM users
    <trim prefix="WHERE" prefixOverrides="AND">
        <if test="ids != null and ids.size() > 0">
            AND id IN
            <trim prefix="(" suffix=")">
                <foreach collection="ids" item="id" separator=",">
                    #{id}
                </foreach>
            </trim>
        </if>
    </trim>
</select>
  • ids = [1, 2, 3] 일 때:
SELECT * FROM users WHERE id IN (1, 2, 3)
  • ids가 비어 있으면 WHERE 절 자체가 생성되지 않음
SELECT * FROM users

 

이렇게 하면 IN 절을 자연스럽게 동적으로 구성할 수 있으며, ids가 비어 있는 경우 WHERE 절 자체가 없어지도록 처리할 수도 있어요.

 

MyBatis의 <trim> 태그를 활용하면 WHERE 1=1을 사용하지 않고도 동적 SQL을 유연하게 구성할 수 있으며, AND, OR 같은 불필요한 키워드를 자동으로 정리하여 가독성을 높일 수 있어요. 또한 SET 절에서도 마지막,를, 자동으로 제거할 수 있어 UPDATE 문을 깔끔하게 만들 수 있으며, IN 절을 구성할 때도 <trim><foreach>를 조합하여 더욱 효율적인 SQL을 작성할 수 있어요. 따라서 <trim>을 잘 활용하면 코드의 중복을 줄이고 유지보수를 더욱 쉽게 할 수 있습니다.

728x90
728x90