코딩마을방범대

MyBatis의 샾(#{})과 달러(${})의 차이 본문

💡 백엔드/Java

MyBatis의 샾(#{})과 달러(${})의 차이

신짱구 5세 2023. 5. 27. 14:55
728x90

 

#{}

  • 쿼리문이 실행되면 아래와 같이 쿼리문에 ?가 생기며 파싱
  • #{}을 사용하는 경우 PreparedStatement를 생성
  • 파싱된 쿼리문은 재활용(캐싱)되기 때문에 효율적
  • 변수에 작은 따옴표(')를 자동으로 붙여 쿼리가 수행됨
SELECT
    name, email
FROM
    user
WHERE
    id = ?

 

 

단점

변수 양쪽에 따옴표가 붙기 때문에 value가 아닌 곳에선 사용 불가 (SQLSyntaxErrorException 발생)

 

예) 아래에선 "FROM user_'1'" 이런식으로 파싱되기 때문에 오류 발생함

<select id="select" resultType="String" parameterType="Map">
    SELECT
        name AS name
    FROM
        user_#{tableId}
    WHERE
        id = #{id}
</select>




${}

  • 값이 넣어진 채로 쿼리문이 수행됨 (파라미터의 값이 바뀔 때마다 항상 쿼리문 파싱을 진행해야 함)
  • 작은 따옴표(')가 붙지 않기 때문에 아래처럼 테이블 이름이나 컬럼 이름을 동적으로 결정할 때 사용할 수 있음

 

단점

SQL Injection에 취약

 

예) 아래와 같은 쿼리를 진행할 때

<select id="selectUserFromTable" parameterType="Map" resultType="...">
    SELECT
        *
    FROM
        user
    WHERE
        id = '${id}' AND password = '${password}'
</select>

파라미터 값이 "admin' --" 로 입력되는 경우 아래와 같이 수행됨

SELECT
    *
FROM
    user
WHERE
    id = 'admin' -- 'AND password = ''

 

즉, where 절에서 비밀번호에 대한 조건은 사라지게 되어 id만 입력해도 관리자 계정 정보를 조회할 수 있게 됨




참고사이트
MyBatis에서 샾(#{})과 달러(${})의 차이는 무엇일까?-MadPlay!

 
728x90

'💡 백엔드 > Java' 카테고리의 다른 글

Spring Security 기초  (0) 2023.05.27
JAVA로 파일 삭제 하기  (0) 2023.05.27
Log - (1) Log4j  (0) 2023.05.27
Contoller의 오류  (0) 2023.05.27
Java로 메일 가져오기  (0) 2023.05.26