Mybatis를 사용해서 쿼리문을 작성하면 파라미터를 작성하는 방법이 두 가지가 있다.
#{}와 ${} 방식이다. 이번 포스팅에서는 두 방식의 차이점에 대해 알아보려고 한다.
#{ }
<SELECT>
SELECT
*
FROM
BOARDS
WHERE
username = #{username}
</SELECT>
BOARDS 테이블에서 username을 조건으로 데이터를 조회하는 쿼리문이다. 해당 쿼리문을 보면 파라미터 부분에 #{}으로 작성한 것을 볼 수 있다.
위 쿼리문이 실행되면 #{} 부분에 ?가 생기면서 아래처럼 파싱 된다.
<SELECT>
SELECT
*
FROM
BOARDS
WHERE
username = ?
</SELECT>
Java JDBC API로 코딩을 할 때, PreparedStatement를 사용하여 파라미터를 바인딩 해준 기억이 있다. #{}을 PreparedStatement와 같다고 보면 된다. 그래서 PreparedStatement를 사용했을 때, 장점을 얻을 수 있다.
예를 들어, 파싱 된 쿼리문은 캐싱되기 때문에 동일한 쿼리일 경우 매번 컴파일 과정이 필요 없기 때문에 효율적이다. 그리고 ${}보다 보안 측면에서 유리하기 때문에 많이 사용한다.
${ }
<SELECT>
SELECT
*
FROM
BOARDS
WHERE
username = ${username}
</SELECT>
값이 넣어진 채로 쿼리문이 실행된다. 그래서 파라미터가 바뀌면 매번 컴파일 과정이 수행되기 때문에 #{}보다 비효율적이다. 즉, ${}은 Statement와 같다고 보면 된다. 그래서 Statement의 특징을 가져온다.
PreparedStatement와 Statement에 대해 알고 싶은 분은 아래 블로그를 참조하시면 좋을 것 같다.
[JDBC] Statement, PreparedStatement 이용하기
자바에서 데이터베이스로 쿼리문을 전송할 때, 사용할 수 있는 인터페이스는 2가지가 존재한다.Statement와 PreparedStatement이다.둘 다 쿼리 전송 기능을 가지고 있지만차이점이 존재하므로 어떤 차
velog.io
그럼에도 ${}를 사용하는 경우가 있다. 예를 들어, 게시물을 오름차순 혹은 내림차순으로 조회하고 싶을 때 사용할 수 있다.
<SELECT>
SELECT
*
FROM
boards
WHERE
id = #{id}
ORDER BY
create_at ${value}
</SELECT>
위 쿼리문을 설명하면 BOARDS 테이블에서 id를 조건으로 create_at이 내림차순 혹은 오름차순으로 조회하는 쿼리문이다.
이런 경우 ${value} 부분에 싱글 쿼테이션이 붙으면 쿼리문이 실행이 안된다. 그래서 극히 제한적인 경우에 사용할 듯하다.
그래서 ${}를 사용하려면 아래처럼 싱글 쿼테이션을 붙여주고 사용해야 하는데 여기서 ${}의 보안 문제가 발생한다.
<SELECT>
SELECT
*
FROM
boards
WHERE
id = '${id}'
ORDER BY
create_at ${value}
</SELECT>
SQL Injection
<SELECT>
SELECT
*
FROM
MEMBER
WHERE
username ='${username}' and password = '${password}'
</SELECT>
위 쿼리문은 기본적으로 로그인을 진행하는 데 사용하는 쿼리문이다. 만약에 username의 값으로 admin' -- 이라는 값이 들어온다고 가정해보자.
SELECT
*
FROM
MEMBER
WHERE
username = 'admin' -- ' and password = '';
그러면 password에 대한 where절의 조건은 사라지고 admin으로 관리자 계정에 접근하게 된다. 어디까지나 관리자의 계정이 admin이라는 가정 하에 말하는 것이다. 이처럼 ${}은 #{}보다 보안 측면에서 약점을 보이는 것을 알 수 있다.
정리
- #{}은 PreparedStatement와 동일한 역할을 한다. 그래서 효율적이고 보안에도 유리하다.
- ${}은 Statement와 동일한 역할을 한다. 그래서 #{}에 비해 비효율적이고 보안에도 취약하다.
- ${}은 ORDER BY에서 사용하는 게 아니라면 거의 사용할 일이 없을 것이다.
▽ 도움을 주신 분들
MyBatis에서 샾(#{})과 달러(${})의 차이는 무엇일까?
마이바티스(MyBatis)에서 XML 파일에 쿼리문을 작성할 때, 샾(#{}) 기호와 달러(${}) 기호의 차이점은 무엇일까?
madplay.github.io
[MyBatis] #{} 와 ${} 개념과 차이점
궁금은 했지만 알아보기 귀찮은 #{} 와 ${} 개념과 차이점을 아주 명확하고 확실하게 알아보도록 하겠습니다. 먼저 PreparedStatement 와 Statement를 알아야 한다. 간단하게 할게요;; 간 단 하 게 PreparedSta
java119.tistory.com
Mybatis 에서 #{} 과 ${}의 차이
Mybatis 에서 #{} 과 ${}의 차이 /* * [개정 이력] * 2017.12.01 내용 보충 */ 회사에 취직하고나서, 쿼리문을 작성하는데 이상한 점을 발견했다. 바로 Mybatis 를 이용해 XML에 쿼리문을 작성하는데, 파라
logical-code.tistory.com
스프링(Spring) Ibatis/Mybatis에서 ##, #{}과 $$, ${}의 차이점
츄르사려고 코딩하는집사입니다. 스프링(Spring)은 전자정부 프레임워크로 지정되어 사용되는 프레임워크로, 웹개발을 하면 백엔드에서 많이 사용하곤 합니다. 스프링의 특징 중 JDBC를 사용하여
yongku.tistory.com

'Mybatis' 카테고리의 다른 글
[Mybatis] 동적 쿼리에 대해 알아보자 (0) | 2022.07.13 |
---|---|
[Mybatis] CDATA가 뭐지? (0) | 2022.07.12 |
JPA와 Mybatis 차이점 (0) | 2022.06.27 |