MyBatis, #{}과 ${}의 차이
MyBatis를 사용하면
#{}은 ''를 포함한 매핑 ${}은 ''를 포함하지 않고 매핑이라 단순하게 알고있지만, 좀더 세심하게 살펴보자.
<br/>
우선 PreparedStatement와 Stament를 공부하자.
Stament 코드는 다음과 같다.
String sqlstr = "SELECT name, memo FROM TABLE WHERE num = " + num
Statement stmt = conn.credateStatement();
ResultSet rst = stmt.executeQuerey(sqlstr);
쿼리문에 파라미터를 붙여주어, SQL문을 실행한다.
<br/>
NUM 값이 1이라면, 다음 SQL문이 DBMS로 전송된다.
SELECT name, memo FROM TABLE WHERE num = 1
<br/>
NUM 값이 2라면, 다음 SQL문이 DBMS로 전송된다.
SELECT name, memo FROM TABLE WHERE num = 2
<br/>
서도다른 두 쿼리가 DBMS로 전송되고 DBMS는 다르게 인지하기 때문에 매번 컴파일을 실행한다.
따라서 NUM값을 N개로 하여 조회하면 N번의 컴파일이 이루어질 것다.
<br/>
PrparedStament는 이 점을 보안 할 수 있다.
PrparedStament의 코드는 다음과같다.
String sqlstr = "SELECT name, memo FROM TABLE WHERE num = ? "
PreparedStatement stmt = conn.prepareStatement(sqlstr);
pstmt.setInt(1, num);
ResultSet rst = pstmt.executeQuerey();
<br/>
2번라인을 보자.
<br/>
2번 라인에서는 다음 SQL문을 전송하고, DBMS는 SQL문을 컴파일 한다.
SELECT name, memo FROM TABLE WHERE num = ?
<br/>
SQL문이 실행될때 전송된 NUM값이 파라미터로 전송된다.
전송된 NUM값이 ?에 바인딩되어 SQL문을 실행한다.
<br/>
따라서 N개의 NUM으로 SQL문을 실행하여도, 한번의 컴파일로 해결 할 수 있다.
또한 SQL문 원본은 이미 고정되어 컴파일되어있기때문에
어떤 파라미터값이 바인딩 되어도 SQL문은 고정되며 이로 인하여 SQL Injection을 보안하는 것에 좋다.
<br/>
그럼 Stament 코드를 왜쓰는가?
파라미터가 아닌, SQL문을 다이나믹하게 하는 것에 사용한다.
예를들어 다음과 같을 것이다.
String sqlstr = "SELECT name, memo FROM TABLE_" + num;
PreparedStatement stmt = conn.prepareStatement(sqlstr);
pstmt.setInt(1, num);
ResultSet rst = pstmt.executeQuerey();
<br/>
NUM값에 따라 테이블명을 변경하여 다이나믹하게 SQL문을 작성할 때 유용하다.
그러나 SQL Injection 공격에 취약하기 때문에, 개발자가 별도의 설정을 해주어야한다.
<br/>
그럼 MyBatis에서 #{}, ${}의차이는?
#{}은 PreparedStament이다. #{} 구문은 ? 로 변경되어 DBMS에 SQL문이 캐싱되어진다.
추후에 바인딩되기 때문에 ?값이 달라져도 같은 컴파일이 된 내용을 재사용할 수 있다.
또한 ''가 자동으로 생성된다.
<br/>
${} Statment이다. ${}구문은 ? 아닌 새로운 쿼리로 실행된다.
따라서 SQL문 자체가 변경되고 컴파일되며, SQL Injection에 취약하다.
또한 '' 가 자동으로 생성되지 않는다.
<br/>
<br/>
참조
<a href="http://devbox.tistory.com/entry/Comporison">http://devbox.tistory.com/entry/Comporison</a>
<a href="https://en.wikipedia.org/wiki/Prepared_statement">https://en.wikipedia.org/wiki/Prepared_statement</a>
<br/>
<br/>