본문 바로가기

SpringFramework/Spring

Spring - Mybatis 샵(#)과 달러($)의 차이

Mybatis 프레임워크를 사용할 때 XML파일에 쿼리문을 작성한다. 그리고 쿼리문을 작성할때 필요 인자들을 보내주고, 쿼리 바인딩을 사용하여 인자들을 매핑한다. 매핑을 할 때 샵(#)과 달러($)를 사용하는데, 두개의 차이는 무엇일까?

<!-- 샵(#) 사용 -->
<select id="userList" parameterType="userRequestDto" resultType="userVO">
SELECT
	user_id,
    user_name,
    user_age,
    user_email,
    user_phone
FROM
	users
WHERE
	user_name = #{user_name}
</select>

<!-- 달러($) 사용 -->
<select id="userList" parameterType="userRequestDto" resultType="userVO">
SELECT
	user_id,
    user_name,
    user_age,
    user_email,
    user_phone
FROM
	users
WHERE
	user_name = ${user_name}
</select>

샵(#)으로 쿼리바인딩

파라미터가 String 형태로 들어와 자동적으로 싱글쿼터가 붙어서 [user_name = '장윤상'] 이라는 형태가 된다. 쿼리문이 실행되면 [user_name = ?]가 생기며 파싱되는 동작 방식을 갖는다.

이 방법은 쿼리 주입(SQL Injection) 공격을 예방할 수 있다. 그리고 이렇게 파싱된 쿼리문은 정적인 방법을 사용하기 때문에 캐싱을 해서 재활용할 수 있어서 효율적이다.

달러($)로 쿼리바인딩

파라미터가 바로 출력된다. 위의 예제에서는 [user_name = 장윤상] 이라는 형태가 된다. 샵과 달리 자동으로 싱글쿼터를 붙여주지 않기 때문에, 쿼리오류가 발생할 것이다.

이 방법은 테이블명이나 컬럼명을 동적으로 결정할 때 사용한다. 혹은 ORDER BY 절을 사용할때는 자동으로 싱글쿼터가 붙으면 안되기때문에 특정 상황에서는 사용하기도 한다.

이 방법은 동적쿼리 방식이기 때문에 새로운 쿼리로 인식하여 캐싱사용이 불가능하여 성능상으로 좋은편은 아니다. 그리고 이 방법의 큰 문제점은, SQL Injection 공격에 취약하다.

 

간단한 예를 들어봤을때.. 만약 ${user_name}에 ['해커' OR 1=1] => [WHERE user_name = '해커' OR 1=1] 라는 내용이 입력된다면 어떻게 될까?? 회원정보 다털린다..

 

참고자료

= https://logical-code.tistory.com/25

'SpringFramework > Spring' 카테고리의 다른 글

Spring - PSA  (0) 2022.04.07
Spring - 스케줄러 중복실행 이슈분석  (0) 2022.03.14
Spring - Mybatis FrameWork 여러 스키마 적용하기  (0) 2022.02.08
Spring - 인스턴스 변수 참조  (0) 2021.10.20
Spring - Redis 연동  (0) 2021.10.20