Sql

동적 쿼리 Where절

배고픈 징징이 ㅣ 2023. 1. 20. 09:27

1. Where 1=1

▶ WHERE 1 = 1 을 사용했던 이유

   - 동적 쿼리에서 WHERE절 최상단에 1 = 1 을 적어 놓으면

      Mybatis의 If문 작성도 편하게 AND로 처리할 수 있고, 주석 처리또한 쉬워진다.

▶ WHERE 1 = 1 의 위험성

   - SELECT문에서는 심각한 문제까지는 아니지만 문제가 발생한다.

<select id="selectUser" resultType="kr.test.dto.user.userInfo">
    SELECT id, name
    FROM db_user.dbo.tbl_user
    WHERE 1=1
        <if test="userid != null and userid != ''">
            AND userid = #{userid}
        </if>
</select>

위 쿼리에서 userid가 없을 경우, 전체 회원이 조회되는 이슈가 발생한다.

 

   - UPDATE, DELETE문에서는 심각한 문제 발생이 야기된다.

<update id="updatetUser">
    UPDATE db_user.dbo.tbl_user
    SET user_alias = #{user_alias}
    WHERE 1=1
        <if test="userid != null and userid != ''">
            AND userid = #{userid}
        </if>
</update>

위 쿼리에서는 userid가 없을 경우, 전체 회원의 별명이 업데이트되는 심각한 문제가 발생된다.

 

2. where 태그

▶ WHERE 1 = 1 의 대체 where 태그

   - where 태그가 맨 첫 조건의 AND는 자동으로 제외시켜 준다.

<update id="updatetUser">
    UPDATE db_user.dbo.tbl_user
    SET user_alias = #{user_alias}
    WHERE
        <where>
            <if test="userid != null and userid != ''">
                AND userid = #{userid}
            </if>
        </where>
</update>

하지만 이 쿼리 또한 userid가 없다면 전체 회원의 별명을 업데이트 시킨다.

 

3. trim 태그

▶ WHERE 1 = 1 의 대체 trim 태그 (정답)

   - prefix="WHERE "이 있는 경우

<update id="updatetUser">
    UPDATE db_user.dbo.tbl_user
    SET user_alias = #{user_alias}
    <trim prefix="WHERE" prefixOverrides="AND">
        <if test="userid != null and userid != ''">
            AND userid = #{userid}
        </if>
    </trim>
</update>

위 쿼리 또한 userid가 없다면 WHERE절 자체가 없는것으로 인식되어 전체 회원이 업데이트 된다.

   - prefix="WHERE "을 제거한 경우

<update id="updatetUser">
    UPDATE db_user.dbo.tbl_user
    SET user_alias = #{user_alias}
    WHERE
        <trim prefixOverrides="AND">
            <if test="userid != null and userid != ''">
                AND userid = #{userid}
            </if>
        </trim>
</update>

그디어 전체 회원 업데이트 이슈를 해결하였다.

위 쿼리에서 userid가 없다면 BadSqlGrammarException이 발생하면서 예외 처리된다.

 

4. 끝

▶ 안전한 쿼리를 위한 유효성 검증

- 쿼리에서 trim태그 사용은 마지막 보루의 개념으로 생각하고 예외 발생을 막는것이 더 좋은 프로그램이 될 것 이다.

- DTO에서 valid 옵션으로 체크하는 방법을 추천한다.

반응형