web developer

[ibatis/Mybatis] ibatis/Mybatis에서 #{}, ${} 차이 본문

Persistence Framework/iBatis, MyBatis

[ibatis/Mybatis] ibatis/Mybatis에서 #{}, ${} 차이

trueman 2022. 1. 5. 14:01
728x90
728x90

1. 2가지 관점 
[1] DB관점 : ##은 소프트 파싱, $$은 하드파싱

* DBMS 엔진은 요청받은 쿼리문을 실행하기 위해 파싱(Parsing)이라는 과정을 진행합니다.
* Library cache에 이전에 실행했던 쿼리가 없는 경우 : '하드 파싱(Hard Parsing)' 진행
* Library cache에 이전에 실행했던 쿼리가 있는 경우 : '소프트 파싱(Soft Parsing)' 진행

 

[SQL 실행과정] 파싱(Parsing), 소프트파싱(Soft parsing), 하드 파싱(Hard parsing) - SQL 쿼리 처리 과정

SQL문 실행 과정에 대한 포스팅입니다. DBMS 엔진은 요청받은 쿼리문을 실행하기 위해 파싱(Parsing)이라는 과정을 진행합니다. 이 파싱에는 문법 체크, 권한 유무, Library cache에 기존 쿼리가 있는지

mentha2.tistory.com

[2] JDBC관점 : ##은 파라미터 바인딩, $$은 문자열 replace


2. 주요내용
[1] ibatis #값#,    Mybatis #{값}

<select id="select" resultType="String" parameterType="Map">
    SELECT NAME, ID
    FROM  USER
    WHERE ID = #{id}
</select>

위와 같이 MyBatis에서 #{}이 사용된 쿼리문이 실행되면 아래와 같이 쿼리문에 ?가 생기며 파싱된다.

SELECT NAME, ID
FROM  USER
WHERE ID = ?

쿼리문을 작성할 때 #{}을 사용하는 경우 PreparedStatement를 생성하게 되는데 위의 ?파라미터 바인딩되어 수행된다.
* MyBatis의 해시(#)를 사용한 파라미터는 PreparedStatement의 파리미터와 대응한다. 
* PreparedStatement는 한번 수행한 쿼리를 캐싱하는 객체

(1) #{id}의 값이 abcde이라면 쿼리문에는 id= 'abcde'의 형태가 된다.
* 변수 자료형이 String이면, 자동으로 작은 따옴표를 붙여 쿼리가 수행되기 떄문에 '#{id}'와 같은 식으로 쿼리문을 작성하지 않아도 된다.
(2) 쿼리 주입을 예방할 수 있어 보안측면에서 유리하다.


[2] ibatis $값$,    Mybatis ${값}

<select id="exam_select" parameterType="HashMap" resultType="HashMap">
    SELECT  ${COLUMN}
    FROM    USER
</select>

값이 넣어진 채로 쿼리문이 수행된다. 그렇기 때문에 파라미터의 값이 바뀔 때마다 항상 쿼리문 파싱을 진행해야 한다.

(1) 해당 컬럼의 자료형에 맞추어 Parameter 자료형이 변경된다.
(2) 쿼리 주입을 예방할 수 없어 보안측면에서 불리하다. 그러므로, 사용자의 입력을 전달할때는 사용하지 않는 편이 낫다.
(3) 테이블이나 컬럼명을 Parameter전달하고싶을 때 사용한다.
* 변수의 자료형과 관계없이 작은 따옴표(' ')를 parameter에 감싸지 않기 때문에, Parameter$ 및 ${Parameter}를 사용할 때 작은 따옴표로 처리를 하지 않으면 Column이나 이름을 찾지 못한다는 Error가 발생합니다.


[3] 차이점

#Parameter# 및 #{Parameter} 같은 경우에는 PreparedStatement를 사용하게 되면서, 변수를 Bind를 하게 됩니다. 이 경우에는 바인딩한 것들을 계속해서 바꿔줄 수 있기 때문에 코드의 재사용성이라는 장점이 있고, 변수를 Bind하면서, SQL Injection을 예방을 할 수 있습니다.

$Parameter$ 및 ${Parameter}는 변수에 저장된 값을 Bind하지 않고 Statement를 사용하게 되면서 쿼리문에 들어가는 값을 수정할 수 있고, 이 경우에는 우리가 흔히 알고 있는 SQL Injection의 공격을 받을 수 있습니다. 또한, 쿼리문이 변경되면 쿼리문을 다시 파싱하는 작업을 진행하기 때문에 속도가 저하된다는 단점이 있습니다. 
* DB입장에서는 $$은 이미 문자열로 치환되어서 쿼리가 수행되기 때문에 $$값이 달라지면 하드파싱하게 된다. 


그래서 대부분 Query 문을 짤 때, $ 방식보다는 # 방식을 사용하라고 권장을 하고 있습니다.

 

출처 : https://dev-milk.tistory.com/4
출처 : https://logical-code.tistory.com/25
출처 : https://madplay.github.io/post/difference-between-dollar-sign-and-sharp-sign-in-mybatis

728x90
728x90
Comments