MyBatis의 '${}'와 '#{}'
#{} vs ${}
⚓️서론
mybatis에서 중요한 문법이다. 면접에서도 많이 나오는 질문 중 하나인 것 같다.
필자 역시도 질문을 받았다.
이번 기회에 한번 정리하고 넘어가야겠다.
➡️Statement 와 PreparedStatement
본론에 들어가기 앞서 간단히 Statement 와 PreparedStatement의 차이를 간단히 알고 넘어가자.
두 개의 가장 큰 차이점은 캐시를 사용하는지 안하는지가 큰 차이를 가른다.
✅ Statement를 사용하면
- 매번 쿼리를 수행할 때 3단계를 거친다.
- 쿼리 문장 분석
- 컴파일
- 실행
반면에…
✅PreparedStatement를 사용하면
- 처음에만 3단계를 거치고 cache를 사용하여 담아서 재사용한다.
따라서 반복적으로 쿼리가 수행된다면 PreparedStatement를 사용하는것 좋고 DB에도 부담을 덜 준다.
➡️XML에서 ${ }를 사용하면
1️⃣값이 넣어진 채로 쿼리문을 수행한다.
- 따라서 파라미터의 값이 바뀌다면, 쿼리문 파싱을 매번 진행한다. → 성능이 느림
2️⃣쿼리문에 작은 따옴표(’)가 붙지 않는다.
- 따라서 테이블 이름이나 컬럼 이름을 동적으로 결정할 때 사용 가능하다 →
- cf.
#{ }
는 작은 따옴표(’)가 붙음
<select id="select" resultType="String" parameterType="Map">
SELECT
name AS 이름
FROM
user_${id}
WHERE
id = #{id}
</select>
➡️XML에서 #{ }를 사용하면
#{ }
예제 - 쿼리문
<select id="select" resultType="String" parameterType="Map">
SELECT
name AS 이름
FROM
user
WHERE
id = #{id}
</select>
- MyBatis에서는
#{ }
이 사용된 퀴리가 실행되면 파싱되면서#{ }
→?
으로 된다.
SELECT
name AS 이름, email AS 이메일
FROM
user
WHERE
id = ?
여기서 위에서 간단히 알아봤던 PreparedStatement
개념이 들어간다.
#{ }
을 사용하는 경우 PreparedStatement
를 생성하게 되는데 위의 ?
에 파라미터가 바인딩되어 수행된다.
따라서 파싱된 쿼리문은 캐싱되어서 재활용으로 쓰이기 때문에 효율적으로 쓸 수 있다.
✅작은 따옴표(’)는 자동으로 붙여서 수행된다.
#{id}
→'#{id}'
으로 자동으로 처리해준다.테이블 설계가
user_a
,user_b
각각 구성되어있을 때 , 아래와 같은 방법으로는 작성이 불가하다. 쿼리를 실행하면tableId
작은 따옴표가 붙기 때문에SQLSyntaxErrorException
오류가 발생한다.
<select id="select" resultType="String" parameterType="Map">>
SELECT
name AS 이름
FROM
user_#{tableId}
WHERE
id = #{id}
</select>
➡️SQL Inject
- 보안 관련 이슈
<select id="selectUserFromTable" parameterType="Map" resultType="...">
SELECT
*
FROM
user
WHERE
id = '${id}' AND password = '${password}'
</select>
- 만일 id 파라미터의 값으로
‘admin’
—
이 입력되는 경우 → WHERE 절에서 비밀번호에 조건이 사라지게 되어 id만 입력해도 관리자 계정 정보를 조회할 수 있게 된다. - 결론 :
${}
사용하는 경우 SQL Injection에 취약하다.
SELECT
*
FROM
user
WHERE
id = 'admin' -- 'AND password = ''
📎참고
- Statement 와 PreparedStatement
https://devbox.tistory.com/entry/Comporison
- **MyBatis에서 샾(#{})과 달러(${})의 차이는 무엇일까?**
https://madplay.github.io/post/difference-between-dollar-sign-and-sharp-sign-in-mybatis