mybatis의 쿼리 로그와 바인딩 쿼리의 차이로 인한 에러.
2025. 6. 26. 11:23ㆍ에러
현상
mybatis 로그에서 찍힌 쿼리는 다음과 같았다.
SELECT * FROM my_table
WHERE ( REGEXP LIKE user_id, '사원찾기파라미터-이름orID 값', 'i'
OR user_id IN
(SELECT user_id FROM user_table WHERE user_nm LIKE '%'||'사원찾기파라미터-이름orID 값' ||'%' )
-- 검색타입이 id, 이름이 분리되어있지 않고 id or 이름으로 검색하는 상황
이 쿼리를 sqlDeveloper를 이용해 오라클에서 직접 쿼리를 실행했을 때는
원하는 데이터가 잘 나왔지만 , DTO에는 값이 세팅되지 않았다.
여러가지 확인해봤지만 mapper ,DTO 등의 문제는 아니었고, 쿼리 자체의 문제였다.
해결
사실 id 검색, 이름 검색을 따로만들어서
동적쿼리가 id검색일 때 id 검색 쿼리, 이름 검색일 때 이름검색 쿼리가 실행되도록 하면 끝.
원인
mybatis에 작성된 쿼리는 다음과 같이 바인딩 된 코드이다.
SELECT * FROM my_table
WHERE ( REGEXP LIKE user_id, #{searchValue}, 'i'
OR user_id IN
(SELECT user_id FROM user_table WHERE user_nm LIKE '%'|| #{searchValue} ||'%' )
-- 검색타입이 id, 이름이 분리되어있지 않고 id or 이름으로 검색하는 상황
로그에 찍히는 건 #{searchValue}에 값이 적용된 쿼리가 찍힌다.
SELECT * FROM my_table
WHERE ( REGEXP LIKE user_id, '한창희', 'i'
OR user_id IN
(SELECT user_id FROM user_table WHERE user_nm LIKE '%'||'한창희' ||'%' )
-- 검색타입이 id, 이름이 분리되어있지 않고 id or 이름으로 검색하는 상황
개발자입장에서는 이 2개의 쿼리가 논리적으로 같아보이지만
오라클입장에서는 서로 다른 쿼리이다.
SELECT * FROM my_table
WHERE ( REGEXP LIKE user_id, :searchValue , 'i'
OR user_id IN
(SELECT user_id FROM user_table WHERE user_nm LIKE '%'|| :searchValue ||'%' )
SELECT * FROM my_table
WHERE ( REGEXP LIKE user_id, '한창희', 'i'
OR user_id IN
(SELECT user_id FROM user_table WHERE user_nm LIKE '%'||'한창희' ||'%' )
이렇게 다른 쿼리로 인식한다.
서버에서 mybatis로 인해 실행되는 쿼리는 :searchValue 이지만,
로그에 찍히는 쿼리는 '한창희' 이다.
오라클에서 바인딩방식( :searchValue)로 실행 후 '한창희'를 입력했더니 빈 데이터가 나왔다.
그래서 DTO에 값이 세팅되지 않았던 것.
이거는 오라클의 optimizer가 실행계획을 세울 때
:searchValue의 쿼리와 '한창희' 값을 직접 입력한 쿼리가 다르다보니
서로 다른 실행 계획을 만들면서 실제 쿼리 결과가 다르게 나온것이었다.