진이의 Developer Story
MyBatis #과 $의 차이 본문
개발에는 Copy&Paste 를 사용하다 보니, #과 $을 유심히 본적이 없었습니다.
아침에 출근해서 작일 작성한 mapper 파일을 살펴보는데 눈에 띄었습니다.
SELECT COUNT(*) FROM USER
WHERE ID = #{id}
위의 구문을 살펴보면 #이고 다른 구문 중엔 $이 사용되는 겁니다.
알아본 결과로는 PreparedStatement(#, 동적)와 Statement($, 정적)의 차이입니다.
1. PreparedStatement(#, 동적)
다음 예제로 확인해보겠습니다.
// 작성된 매퍼구문 (id = admin)
SELECT COUNT(*) FROM USER WHERE ID = #{id}
// DBMS에서 받는 쿼리
SELECT COUNT(*) FROM USER WHERE ID = ?
// 실제 수행 쿼리
SELECT COUNT(*) FROM USER WHERE ID = 'admin'
보시다시피 실제로 수행되는 쿼리는 PreparedStatement 를 사용하는 것과 같이 바인딩됩니다.
#을 사용하면 호따옴표(Single quotation)를 쓰지 않아도 되는거죠~
2. Statemnet($, 동적)
이번엔 $의 예제를 확인해보겠습니다.
// 작성된 매퍼구문 (id = admin)
SELECT COUNT(*) FROM USER WHERE ID = '${id}'
// DBMS에서 받는 쿼리
SELECT COUNT(*) FROM USER WHERE ID = 'admin'
// 실제 수행 쿼리
SELECT COUNT(*) FROM USER WHERE ID = 'admin'
$를 사용하면 단순히 문자열이 치환(replace)되기 때문에 호따옴표는 꼭 적어주셔야 합니다.
일반적으로 #을 쓰도록 권장이 되있지만 $을 써야 하는 경우도 있습니다.
#을 써야 하는 이유부터 알아보자면, 바로 보안에 직결되는 문제이기 때문입니다.
// 작성된 매퍼구문 (id = admin'–– , password = 1234)
SELECT COUNT(*) FROM USER WHERE ID = '${id}' AND PASSWORD = '${password}'
// DBMS에서 받는 쿼리
SELECT COUNT(*) FROM USER WHERE ID = 'admin'-- ' AND PASSWORD = '1234'
// 실제 수행 쿼리
SELECT COUNT(*) FROM USER WHERE ID = 'admin'
위와 같이 WHERE ID = 'admin' 이하의 조건절은 주석처리가 되기 때문에 아무나 관리자 아이디로 접근할 수 있기 때문입니다.
마지막으로 $을 써야 하는 경우는 컬럼명을 바인딩해야 하는 경우입니다.
// 작성된 매퍼구문 (colname = ID)
SELECT ${ID} FROM USER
// DBMS에서 받는 쿼리
SELECT ID FROM USER
// 실제 수행 쿼리
SELECT ID FROM USER
위와 같은 경우는 PreparedStatement로는 바인딩을 할 수 없고, Statement를 사용해야 합니다.
다만, 아까도 말했듯이 문자열 치환인 만큼 보안에 각별히 신경을 써야할 것입니다.
'DBMS' 카테고리의 다른 글
눈으로 확인하는 SQL JOIN 문 (0) | 2016.05.26 |
---|
Comments