SPRING 에서 mybatis를 사용하다 보면
mapper에서 보이는 '#' 과 '$'
특히 나는 기존에 배울때 '#'에 대해서만 배웠기 때문에
'$' 표현이 생소하기 때문에 어떤 의미인지 공부하며 기록해두고자 한다.
우선 #{} 을 이용했을 경우의 실행방식을 살펴보자
>mapper
SELECT * FROM mineTest
WHERE num = #{num} AND id = #{id}
이런식으로 작성된 쿼리문은 다음과 같이 오라클로 전달되어 수행된다.
>oracle로 전달
SELECT * FROM mineTest
WHERE num = ? AND id = ?
>실제 수행 쿼리문
SELECT * FROM mineTest mt
WHERE num = 34 AND id = 'mine'
다음은 ${}를 이용했을 경우의 실행방식을 살펴보자
>mapper
SELECT * FROM mineTest
WHERE num = ${num} AND id = ${id}
이런식으로 작성된 쿼리문은 다음과 같이 오라클로 전달되어 수행된다.
>oracle로 전달
SELECT * FROM mineTest
WHERE num = 34 AND id = mine
>실제 수행 쿼리문
SELECT * FROM mineTest mt
WHERE num = 34 AND id = mine
이렇게 간단하게 둘의 실제 실행방식의 차이점을 확인해 봤는데
더 깊숙하게 들어가 보자면
1. preparedStatement 와 Statement 의 차이점이라 보면된다 (쉽게 동적 과 정적의 차이)
2. 오라클로 전달할때 '?' 와 '값' 형태로 바인딩 된다.
3. preparedStatement 방식인 #{} 은 쿼리의 재사용이 가능하지만
Statement 방식인 ${} 은 재사용이 불가능하며 새로운 쿼리로 인식하기 때문에 성능상 차이가 존재한다.
- 성능상에 차이가 있다하지만 ${} 가 단점만 존재하는게 아니라 옵티마이저 수행 계획에 이점을 주는 경우도 존재하며 자주 바뀌지 않거나 사용자의 입력을 받는 경우 (ex 테이블 명 , 컬럼 명) 에 사용해 주면 좋다.
- #{} 은 사용자의 입력을 받거나 데이터가 많은 경우에 주로 사용한다.
(대부분 ${} 보다는 #{} 위주로 작성하는 경우가 많다.)
4. ${}을 사용할 경우 SQL Injection 보안 위험이 발생하는 경우가 발생한다.
- 위의 예시를 보여준것처럼 ${}는 #{} 과 달리 문자열에 자동으로 ' ' 쿼터를 감싸주지 않는다.
댓글