본문 바로가기
DB

mybatis where 1=1

by sihyeong 2024. 1. 9.

1. WHERE 1=1

WHERE 1=1은 항상 참을 의미한다.

 

2. 사용 이유

2-1 쿼리 디버깅 시 주석 처리가 간편함.

SELECT *
FROM STUDENT
WHERE AGE = '10'
AND NAME = 'tom'

 

SELECT *
FROM STUDENT
WHERE -- AGE = '10'
-- AND 
NAME = 'tom'

 

AND절 때문에 주석을 두번이나 달아야 한다.

이때 WHERE 1=1을 사용하면 비교적 쉽게 주석처리 할 수 있다.

SELECT *
FROM STUDENT
WHERE 1 = 1
-- AGE = '10'
AND NAME = 'tom'

 

2-2 동적쿼리의 where절 작성이 편하다.

SELECT *
FROM STUDENT

WHERE 1 = 1

<if test="age != null and age != ''">
  AND AGE = '10'
</if>

<if test="name != null and name != ''">
  AND NAME = 'tom'
</if>

 

3. 문제점

SELECT *
FROM STUDENT

WHERE 1 = 1

<if test="age != null and age != ''">
  AND AGE = '10'
</if>

<if test="name != null and name != ''">
  AND NAME = 'tom'
</if>

 

위와 같은 코드에 age, name값이 모두 null이 온다면 아래와 같은 코드가 되어 STUDENT의 모든 데이터를 조회할 것이다.

SELECT *
FROM STUDENT
WHERE 1 = 1

 

 

만약 해당 코드가 SELECT문이 아닌 DELETE문이나 UPDATE문이라면 모든 데이터가 삭제되거나 값이 틀어질 것이다.

프론트에서 넘어오는 데이터를 모두 null 체크를 한다면 상관없지만, 완벽하게 할수도 없고 실수 한번이라도 한다면 대참사가 일어난다.

 

4. WHERE 1=1 피하기

SELECT *
FROM STUDENT
WHERE
<trim prefixOverrides="AND">
  <if test="age != null and age != ''">
    AND AGE = '10'
  </if>

  <if test="name != null and name != ''">
    AND NAME = 'tom'
  </if>
</trim>

 

trim은 태그 내부에서 실행할 쿼리를 생성해 주는 역할을 한다.

prefixOverrides 속성은 태그 안에서 실행될 쿼리의 가장 앞 쿼리가 해당 속성값과 같다면 해당 문자를 제거하는 기능을 한다.

 

SELECT *
FROM STUDENT
WHERE
  AND AGE = '10'
  AND NAME = 'tom'

 

위와 같이 이상한 쿼리가 생기지 않도록 WHERE 다음에 AND를 제거해서 아래와 같은 쿼리를 만들어 준다.

 

SELECT *
FROM STUDENT
WHERE
  AGE = '10'
  AND NAME = 'tom'

 

 

 

4번의 첫코드를 실행 후 name과 age가 모두 null인 경우 다음과 같은 쿼리가 만들어진다.

SELECT *
FROM STUDENT
WHERE

 

당연하게도 SQL 문법이 틀렸기 때문에 해당 쿼리가 실행되지 않고 BadSqlGrammarException이 발생되며 종료된다.

 

'DB' 카테고리의 다른 글

[oracle] ORA-28001: the password has expired  (0) 2024.03.09
저장 프로시저 (Stored Procedure)  (0) 2024.02.26