Mybatis #과 $ 매핑기호의 차이점
이슈가 발생해서 수정 요청이 들어왔다.
쿼리 insert 하는 부분에서 컬럼에 바인딩 되는 값 안에 작은 따옴표(')
가 들어가 있는 경우 SQLException이 발생했다.
그래서 이 부분을 작은 따옴표가 있더라도 insert 하도록 수정하는 것이다.
소스코드는 내가 작성하지 않았지만, 나도 생각 없이 작성 했었을 것 같다.
알고보니 #, $에 따른 매핑기호로 인한 바인딩 방식 차이로 생긴 문제여서
SQLException에 대한 예외처리와 매핑기호를 $에서 #로 수정
해주어 해결됐다.
그럼 #과 $는 어떤점이 다를까?
#
#은 PreparedStatement
를 의미한다.
예를들어 USER_ID = SeokHun 이고, 아래 쿼리가 실행된다면
SELECT USER_ID FROM USERS WHERE USER_ID = #{USER_ID}
디비에서 받는 쿼리는
SELECT USER_ID FROM USERS WHERE USER_ID = ?
이렇게 물음표(?)
기호로 변수가 바인딩 된다.
그래서 최종 실행되는 쿼리는 아래와 같다.
SELECT USER_ID FROM USERS WHERE USER_ID = 'SeokHun'
$
$는 Statement를 의미한다.
위의 예제와 같은 쿼리를 실행시킨다면, 디비에서 받는 쿼리는 아래와 같다.
SELECT USER_ID FROM USERS WHERE USER_ID = 'SeokHun'
#일 때와 달리 벌써 변수 값이 들어가 있다.
최종 실행되는 쿼리는 둘다 같다.
- 차이점은 디비에서 쿼리를 바인딩해서 받는 방식이다.
바인딩해서 받는 방식이 다른건 알겠는데 그게 그렇게 큰 차이인가?
$를 사용
이미 변수 값에 'SeokHun'이 들어간 상태로 DB에서 파싱을 하게 된다.
-
따라서 변수 값이 바뀔 때 마다 매번 DB에서 파싱을 한다.
- 이는 성능 저하를 야기시키는 요인이 된다.
-
또한 SQL Injection에 취약하다.
-
$의 경우 String이 작은 따옴표(')로 감싸지지 않기 때문에 에러가 발생한다
- 이번 이슈의 경우 이 에러에 해당.
#을 사용
이미 파싱되어 있는 쿼리문을 재활용하게 된다.
-
매번 DB에서 파싱을 하지 않아도 된다.
-
SQL Injection에 대비가 가능하다.
-
작은따옴표(') 사용가능.
결론
#과 $에 따른 차이점을 이해하고 상황에 맞게 사용하자!!!