개발/Database

(MyBatis) Mysql tinyint(1) boolean이 integer로 바뀌는 현상

신매력 2015. 9. 17. 17:58

Mysql의 컬럼 타입 중 tinyint(1)은 0이면 false, 0보다 크면 true를 반환하므로,

boolean으로 주로 사용하고 있다.

 

query.xml

<select id="selectYn" resultType="hashmap">
   SELECT test_yn FROM test LIMIT 1
</select>

 

DAO.java

public Map<String, Object> selectYn() {
	return sqlSessionTemplate.selectList("selectYn");
}

 

이해하기 쉽게 boolean 컬럼 한 행을 가져오는 쿼리로 예를 들어봤다.

 

test_yn이 tinyint(1) 이라면 나는 결과 값을 hashmap으로 받았으니

{"test_yn" : false}  이런식으로 받아질 것이고,

Boolean으로 캐스팅해서 test_yn 값을 쓸 수 있다.

 

 

그런데 쿼리를 아래와 같이 바꿔보았다.

<select id="selectYn" resultType="hashmap">
   SELECT test_yn FROM
   (
 (SELECT test_yn FROM test_yn LIMIT 1)
 UNION
 (SELECT test_yn FROM test_yn LIMIT 1)
    ) AS A
   LIMIT 1
</select>

 

예제라서 말도안되는 쿼리긴 하지만

같은 테이블에 필터링을 건 것들을 서브쿼리 + UNION으로 가져오는 것이라고 생각하자.

 

좀 복잡하긴 해도 같은 테이블의 같은 컬럼을 가져오는데

값은 {"test_yn" : false}이 아니라 {"test_yn":1} 이다.

즉 값이 boolean이 아니라 integer라는 것이다.

 

다른거라고는 UNION을 쓰는 것 뿐인데..

 

처음에는 mybatis의 문제인가 해서 resultMap으로 javaType을 지정해보고 해봤지만

소용이 없었다.

 

 

결론은

MySql에서 UNION하는 경우에 tinyint(1)가 tinyint(4)로 변환된다는 것이다.

 

버그인지 의도한건지 알 수 없지만 버그리포팅에 올라와있었다.

https://bugs.mysql.com/bug.php?id=61131

 

 

 

나는 그냥 instanceof로 판단해서 쓰기로 했다. (boolean으로 받기도하고, integer로 받을수도있고 공통처리를 하고있어서)