[error] java.lang.nullpointerexception 오류 - 1
콘솔창에 오류기록이 없는 상태에서 값이 null로 불러와지는 경우
<select id="selectClassVi" resultType="classDTO" parameterType="String">
<![CDATA[
SELECT * FROM ALTO_CLASS
WHERE CLASS_CODE = #{class_code}
]]>
</select>
우선 위와 같은 쿼리를 실행할 목적이었으나 화면단에서 값이 불러와지지 않는 문제가 발생 함.
- 쿼리만 따로 실행했을때는 문제없이 실행 (쿼리문제X)
- 화면단 → 컨트롤러 → 서비스 → DAO → 순서대로 파라미터가 잘 흘러가는지 확인 (입력문제X)
그런데 print를 사용해 역으로 출력이 잘되는지 확인하려고 하니 DAO에서부터 nullpointerexception이 발생했다.
파라미터값이 sql문 실행되는 과정에 제대로 적용되지 못하거나
쿼리가 제대로 작동되지 못하거나
뽑아낸 값이 정상적으로 DAO로 넘어오지 못하는 것
세가지 가능성으로 범위를 좁혀 재테스트를 해보았다.
- classDTO에 대한 typeAliases가 잘 적용되어있는지 확인 (이상없음)
- 쿼리에 파라미터 값을 수기로 작성해서 테스트 (이상없음)
확실히 파라미터가 적용되는 문제라는걸 알수있었고 긴 삽질끝에 원인을 찾아냈다
그래서 찾아보니 이번 문제의 경우에는 #{}로 작성했던 것을 ${}로 수정해주면 간단히 해결 되는 문제였다.
하지만 나의 경우 #{}으로 주로 사용하도록 배워 ${}의 정확한 사용법을 몰랐기에
이번 기회로 두가지의 명확한 차이를 외워두려 한다
간단히 설명하자면
#{}는 ‘‘가 씌워진 형태로 반환되며, 값에 사용된다.
${}는 ‘‘가 없는 형태로 반환되며, 테이블명이나 컬럼명에 사용된다
일단 일전 JSP를 공부하며 작성했던 PreparedStatement와 Statement 개념이 다시 등장하는데
#{}
사용시 PreparedStatement와가 생성된다.
따라서 PreparedStatement가 제공하는 매개변수값이 설정되며, ?를 대체할 값을 지정하는 것이다.
들어오는 데이터를 문자열로 인식하기 때문에 자동으로 따옴표가 붙는다
PreparedStatement의 장점과 동일하게 매번 컴파일을 하지 않아도 돼 성능상 이점이 크다
${}
Statement를 생성하며, 매개변수 값을 ‘그대로’ 전달한다. 그대로 전달하기 때문에 따옴표도 붙지 않는다
여러 이유가 있겠지만 ORDER BY 함수를 사용할때 자동 따옴표가 붙으면 함수가 적용되지 않는 문제가 있기때문에 ${}를 사용한다.
다만 성능이 좋지않고 보안에 취약한 문제가 있으니
가급적 지금처럼 꼭 필요한 경우가 아니라면 #{}을 쓰는것이 좋다고 한다.