Mybatis 에서 #{} 과 ${}의 차이
/*
* [개정 이력]
* 2017.12.01 내용 보충
*/
회사에 취직하고나서, 쿼리문을 작성하는데 이상한 점을 발견했다.
바로 Mybatis 를 이용해 XML에 쿼리문을 작성하는데, 파라메터 작성법이 그동안 내가 해왔던 것과는 다른 것이었다.
아래는 그동안 내가 써왔던 방식이다.
1 2 3 4 5 6 7 | <select id="select_list" parameterType="HashMap" resultType="HashMap"> SELECT USER_NM , USER_ID FROM USER WHERE USER_ID = ${USER_ID} AND USER_PWD = ${USER_PWD} </select> | cs |
그리고 이건 회사에서 사용하는 방식이다.
1 2 3 4 5 6 7 | <select id="select_list" parameterType="HashMap" resultType="HashMap"> SELECT USER_NM , USER_ID FROM USER WHERE USER_ID = #{USER_ID} AND USER_PWD = #{USER_PWD} </select> | cs |
무슨 차이가 있는지 보이는가? 바로 ${} 가 #{} 로 바뀌었다!
왜? 왜 $을 안쓰고 #을 쓸까? 너무 궁금해서 찾아보았다.
#{}
파라매터가 String 형태로 들어와 자동적으로 '파라메터' 형태가 된다.
예를들어, #{user_id}의 user_id의 값이 abc라면 쿼리문에는 USER_ID = 'abc'의 형태가 된다.
쿼리 주입을 예방할 수 있어 보안측면에서 유리하다.
${}
파라매터가 바로 출력된다.
해당 컬럼의 자료형에 맞추어 파라매터의 자료형이 변경된다.
쿼리 주입을 예방할 수 없어 보안측면에서 불리하다. 그러므로, 사용자의 입력을 전달할때는 사용하지 않는 편이 낫다.
테이블이나 컬럼명을 파라메터로 전달하고싶을 때 사용한다. #{}은 자동으로 ''가 붙어서 이 경우에는 사용할 수 없다.
1 2 3 4 5 | <select id="select_list" parameterType="HashMap" resultType="HashMap"> SELECT ${COLUMN} FROM USER </select> | cs |
<원문>
1. #The incoming data as a string, the incoming data to automatically add a double quotation marks. Such as: order by #{user_id}, if the incoming value is 111, then parsed into SQL values for the order by'111', if its value is ID, then parsed into SQL order by 'id'. 2. $The incoming data directly display generation in sql. Such as: order by ${user_id}, if the incoming value is 111, then parsed into SQL when the value of order by 111, if its value is ID, then parsed into SQL order by ID. 3. #Can significantly prevent SQL injection. 4.$Unable to prevent Sql injection. 5.$General way for incoming database objects, such as into the table name, column names 6 in general can be used # don't use$. Need to pay attention to using the order by dynamic parameters of MyBatis ranking, with $instead# String replace By default, the use of #{} format syntax will cause MyBatis to create pretreatment statement attributes and used it as the setting value (such as security?). It is safe to do this very quickly, also is the preferred approach, sometimes you just want to directly insert a does not change the string in the SQL statement. For example, like ORDER BY, you can use: ORDER BY ${columnName} This MyBatis does not modify or string literal. Important: to accept from the user output and provides the string to the statement unchanged, it is unsafe to do so. This leads to potential SQL injection attacks, therefore you should not allow the user to enter these fields, or often to escape and check. |