[Mybatis] HashMap #{} SQL Syntax에러 처리
2021. 3. 23. 11:45
[Mybatis] HashMap #{} SQL Syntax에러 처리
문제 발생
- 실습 과제중에 사원들을 월급별로 정렬 할 때 desc / asc 값을 Hashmap형태로 보내주었는데 내가 생각한대로 짰을 때 SQL 쿼리 에러 발생 했음
코드 과정
- Servlet에서 order값을 String에 담은뒤 service에는 String으로 일단 넘겨줌
- service에서 order를 HashMap<String, String> = ("order", order) 형태로 묶어서 dao로 넘김
- dao에서 mapper에 map으로 parameter넘겨 줬음
- mapper에서 sql문을
<select id = "order" resultType="EmpDTO" parameterType="HashMap">
select empno, ename, job, mgr, to_char(hiredate, 'YYYY-MM-DD') hiredate, sal, comm, deptno
from emp
order by sal #{order}
</select>
이런식으로 짰는데 오류 생겼음, 요인은 order값을 asc나 desc로 인식을 못한것 같음
해결책
- 첫번째로 알게된 점은 #{param} 형태로 처리하면 String 타입일 경우 자동으로 ' ' 처리가 된다는 것이었다.
- 즉, 내가 예상하는 order by sal desc가 아닌 order by sal 'desc'의 형태가 되기 때문에 오류가 발생하는 것이었다.
- 그렇기 때문에 만약 내가 원하는대로 출력을 하고 싶으면 #{}가 아닌 ${}를 사용해야한다.(#{}와 ${}의 차이는 추후 포스팅 할것이다.)
- 만약 map의 형태로 안전하게 출력을 하고 싶다면
<select id = "order" resultType="EmpDTO" parameterType="HashMap">
select empno, ename, job, mgr, to_char(hiredate, 'YYYY-MM-DD') hiredate, sal, comm, deptno
from emp
<if test = "order == 'desc'">
order by sal desc
</if>
<if test = "order == 'asc'">
order by sal asc
</if>
</select>
- test에 key를 넘겨주면 value값을 비교하기때문에 동적 할당을 통해 비교하게 되면 성공적으로 출력이 된다.
번외
- 해결방법중 ${}를 사용하는 것과 map이 아닌 애초에 String으로 넘기는 경우를 해보았음
- ${}를 사용할 경우 hashmap으로 넘겨주는 형태는 유지하면서 mapper에서 감싸주는 형태만 변환
<select id = "order" resultType="EmpDTO" parameterType="HashMap">
select empno, ename, job, mgr, to_char(hiredate, 'YYYY-MM-DD') hiredate, sal, comm, deptno
from emp
order by sal ${order1}
</select>
- map에다가 데이터를 ("order1", order)형태로 저장했음 key, value넘겨주는게 헷갈려서..
- 아무튼 이렇게하면 성공적으로 실행이 된다.
- ${}의 경우 parameter를 변환없이 그대로 넘겨주는 것이기 때문에 SQL injection문제에 취약하기 때문에 order by와 같은 경우를 제외하고 #{}를 쓴다고 한다.
- 그것마저 불안하다면 #{}를 쓰는게 맞을듯?
- String으로 넘겨주는 경우도 if동적 할당을 해주거나 ${}을 통해 작업한다면 처리 가능할듯
'skill > Mybatis' 카테고리의 다른 글
[Mybatis] 동적쿼리 foreach 사용해서 delete (0) | 2021.04.08 |
---|