| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
- 타임리프Escape
- cmd에서java파일실행
- spring
- 타임리프기본객체
- 정보처리기사실기
- 이클립스없이cmd
- git
- 타임리프Unescape
- 타임리프URL
- thymeleaf
- mysql설치하기
- 정처기실기요약
- mysql
- 타임리프변수
- 타임리프 표현식
- HelloWorld출력
- 개체관계모델
- 정보처리기사
- 스프링부트설정
- 타임리프유틸리티객체
- MySQL설치순서
- 정보처리기사실기요약
- 타임리프날짜
- mysql다운로드
- 타임리프SpringEL
- java
- ER모델
- 타임리프 특징
- mybatis
- 정처기실기
- Today
- Total
ye._.veloper
[ D B ] Mybatis ${}와 #{}의 차이 본문
Mybatis에서 XML파일에 쿼리를 작성하다 문득 ${ }과 #{ }로 파라미터를 가져오는 차이점이 궁금해져서 알아봤다.
아래는 ${ }와 #{ }의 차이를 알아보기 위해 작성한 예시이다.
(아래 예시는 아이디의 수(count)를 구해 같은 아이디가 있는지 중복 검사를 하는 쿼리이다.)
<select id="idCheck" parameterType="userDto" resultType="int">
SELECT COUNT(*)
FROM user
WHERE user_id = ____________
</select>
밑줄 친 부분에 #{ }, ${ }가 들어갈 두 가지의 경우의 과정과 장,단점을 비교해보자
☁ #{ }
<select id="idCheck" parameterType="userDto" resultType="int">
SELECT COUNT(*)
FROM user
WHERE user_id = #{user_id}
</select>
# : PreparedStatement를 의미
◽ 사용 과정
1 ) PreparedStatement 생성
2 ) PreparedStatement parameter 값 안전하게 생성
3 ) PreparedStatement가 제공하는 Set 계열의 method를 사용하여 ?(물음표)를 대체할 값을 지정
4 ) 전달해 온 parameter를 String으로 인식 ➡ 자동으로 따옴표(Quotation)가 붙음
◽ 사용 이유
· 안전하고 빠르기 때문에 사용 권장
⚡ 빠른 이유
- Prepared(준비)
위에서 언급한 "준비"는 컴파일(Parsing)을 의미하며, 컴파일이 미리 되어있기 때문에 Statement에 비해 성능에 이점이 있다.
◽ 특징
· 파라미터가 String 형태로 들어가 자동으로 따옴표(Quotation)가 붙는다.
➡ WHERE user_id = 'user1'
· 쿼리 주입을 예방할 수 있어 보안 문제(SQL Injection)에서 유리하다.
MyBatis에서 위와 같은 #{}이 사용된 쿼리문이 실행되면 아래와 같이 쿼리문에 ?(물음표)가 생기며 파싱된다.
<select id="idCheck" parameterType="userDto" resultType="int">
SELECT COUNT(*)
FROM user
WHERE user_id = ?
</select>
· #{}을 사용하는 경우, PreparedStatement를 생성하게 되는데 위 ?(물음표)에 파라미터가 바인딩되어 수행된다.
이렇게 파싱된 쿼리문은 재활용(캐싱)되기 때문에 효율적이다.
➡ #{ }에 담긴 parameter 값이 달라져도 같은 쿼리로 인식하여 속도가 빠르다.
· 변수에 작은 따옴표(‘)가 자동으로 붙기 때문에 '#{user_id}' 이런 식으로 직접 따옴표를 붙이지 않아도 된다.
· #{ }를 사용하는 경우는 사용자의 입력을 받는 경우 또는 데이터가 많은 경우에 사용한다.
☁ ${ }
<select id="idCheck" parameterType="userDto" resultType="int">
SELECT COUNT(*)
FROM user
WHERE user_id = ${user_id}
</select>
◽ 사용 과정
1 ) Statement 생성
2 ) Statement의 parameter 값을 그대로 전달
3 ) parameter를 그대로 전달하기 때문에 문자열에 따옴표(Quotation)가 붙지 않음
◽ 특징
· { } 안의 파라미터 값 그대로 쿼리문이 수행된다.
➡ WHERE user_id = user1
· 파라미터 값이 넣어진 상태로 쿼리문이 수행되기 때문에 파라미터의 값이 바뀔 때마다 항상 쿼리문에 대한 파싱을 진행해야 한다.
➡ ${ }에 담긴 parameter 값이 달라지면 다른 쿼리로 인식하기 때문에 새로 파싱 작업을 해줘야 함
➡ 속도가 저하될 수 있다. (성능상 단점)
· 쿼리 주입을 예방할 수 없어 보안 문제(SQL Injection)에서 불리하다.
➡ 자주 바뀌거나 사용자의 입력을 받아 쿼리로 전달하는 경우에는 ${ }을 사용하지 않는 것이 좋다.
➡ ORDER BY 사용 시, 따옴표가 붙지 않는 것이 좋으니 ${ }를 사용
· 예를 들어, ${ }를 사용하는 경우는 아래와 같이 테이블명, 컬럼명을 동적으로 결정할 때 사용할 수 있다.
<select id="idCheck" parameterType="userDto" resultType="int">
SELECT COUNT(*)
FROM user_${id}
WHERE user_id = #{user_id}
</select>
- SQLInjection 따로 글 올리기
Ref.
'D B' 카테고리의 다른 글
| [ MySQL ] MySQL 설치하기_2 (MySQL 8.0.x 다운로드) (0) | 2023.02.16 |
|---|---|
| [ MySQL ] MySQL 설치하기_1 (MySQL 8.0.x 다운로드) (0) | 2023.02.15 |
| [ D B ] SQL Injection (0) | 2023.01.24 |
| [ DB ] Join이란? (0) | 2023.01.24 |
| [ MySQL ] Multiple primary key defined - 오류 (2) | 2023.01.21 |