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] 라는 내용이 입력된다면 어떻게 될까?? 회원정보 다털린다..
참고자료
'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 |