mybatis ${}, #{} 차이
서버개발을 할 때 mybatis를 이용해서 mapper에다가 쿼리를 작성하는 일이 많다.
그중에 #{}와 ${} 사용할 일이 생겼는데 어떻게 사용하는지 정리를 해보았다.
1. #{}
select id, pwd from member where id = '홍길동' 이런 쿼리를 mapper에 작성할 때
select id, pwd from member where id = #{parameter} 이런식으로 처리를 하게 된다.
그리고 #{parameter} < 여기에 필요한 값만 전달해주면 그 해당하는 데이터를 조회를 하게 된다.
그리고 #{parameter} 를 사용하게 되면
select id, pwd from member where id = ?
위 쿼리문의 ?에 파라미터가 바인딩되어 수행된다.
한 마디로 #{parameter}에는 파라미터가 String 으로 전달되기 때문에
'홍길동' < 이런식으로 파라미터에 자동으로 작은따옴표(String)가 붙게 된다.
PreparedStatement를 사용해서, 이렇게 파싱된 쿼리문은 재활용(캐싱)되기 때문에 매번 컴파일하지 않아도 되서 성능상 효율적이다.
2. ${}
select id, pwd from member order by birthday desc 이런 쿼리를 mapper에 작성할 때
select id, pwd from member order by ${sortColumn} ${direction} 이런식으로 처리를 하면
${sortColumn} ${direction} 여기에 필요한 컬럼과 desc인지 asc 인지 넣어주면 order by 정렬되서 데이터를 조회하게 된다.
값이 넣어진 채로 쿼리문이 수행된다.
그리고 쿼리문에 #{}을 사용한 것과 다르게 작은 따옴표(‘)가 붙지 않기 때문에
아래처럼 테이블 이름이나 컬럼 이름을 동적으로 결정할 때 사용할 수 있다.
select id from user_${parameter} where id = #{id}
그리고 Statement를 사용해서 매번 컴파일하기 때문에 성능이 떨어진다.
그렇기 때문에 파라미터의 값이 바뀔 때마다 매번 쿼리문 파싱을 진행해야 한다.
즉, 성능상의 단점이 존재한다.
그리고 ${}을 사용하는 경우 SQL Injection에 취약한 부분이 있다.
그래서 보안적인 측면에서 #{}를 사용을 권장하지만 상황에 따라 적절하게 사용하면 될 것 같다.