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의 쿼리와    '한창희'   값을 직접 입력한 쿼리가 다르다보니

서로 다른 실행 계획을 만들면서 실제 쿼리 결과가 다르게 나온것이었다.