본문 바로가기
IT 공부/자바와 웹 애플리케이션

[자바] - JDBC 드라이버 표준 타입 매핑

by exdus3156 2024. 1. 8.

 

1. java의 데이터 타입과 DB의 데이터 타입 변환 문제

개발을 하면서 데이터를 영구 처리하고 싶을 때는 데이터베이스를 활용한다. 이때 데이터베이스는 종류가 굉장히 많은데, 관계형 데이터베이스만 해도 MySQL, Oracle, Postgre 등이 있다.

데이터베이스를 클라이언트 프로그램으로 서버와 직접 통신해서 사용할 수도 있다. 그러나 자바 애플리케이션 개발을 할 때는 자바 애플리케이션이 데이터베이스 서버와 연결을 시도하고 쿼리를 날려야 한다. 이 사이를 매개하는 기술이 JDBC이며, JDBC는 JavaSE 표준이다. 물론 MyBatis, JPA 같은 기술이 많다. 하지만 그 모든 기술도 내부적으로는 JDBC를 사용한다.

그런데 각 데이터베이스는 각자의 데이터 타입을 구현해 사용한다. 대부분 큰 그림에서는 거의 일치하지만, 내부적인 구현 방식은 전부 다 다르다. 심지어 서로에게 없는 데이터 타입도 있다.

따라서 문제가 되는 것은 데이터 타입을 어떻게 처리하느냐다. 일단 자바 애플리케이션은 당연하지만 자바의 기본 데이터 타입 및 객체를 사용할 것이다.

문제는 데이터베이스가 각자의 데이터 타입으로 동작하기 때문에 이 지점에서 데이터 타입을 어떻게 맞춰야 할지 고민이 생긴다. 예를 들어, MaraiDB의 TINYINT 타입의 데이터를 수정하고 싶은데, 자바의 int를 넣어야 할까? 아니면 boolean을 넣어야 할까?

사실 JDBC 기술은 데이터 형 변환에 대해 아주 flexable한 기능을 제공하기 때문에 데이터 변환에 대해 깊게 고민하지 않아도 되지만, 자신이 사용하는 기술이 데이터를 어떻게 변환하는지 알고 있으면 나중에 데이터 문제가 생길 때 대처할 수 있을 것이다.

 

 


2. JDBC 데이터 타입이 매개

java.sql.Types에는 수많은 특수한 데이터 타입들이 명시되어 있다. TINYINT, BIY, BOOLEAN, ... 등 엄청 많다. 바로 이 타입들이 JDBC가 내부적으로 사용하는 데이터 타입이다.

즉, 자바의 기본 데이터 타입(기본 데이터형과 함께 java.lang 패키지에 있는 것들을 말한다)을 JDBC에 전달하면 JDBC는 내부적으로 데이터를 JDBC 데이터 타입으로 변환한다.

JDBC 4.0 spec

그리고 이 JDBC 스펙에 명시된 타입을 각 데이터베이스 벤더(회사)가 개발한 드라이버가 내부적으로 변환을 해서 DB 서버에 맞는 타입으로 변환해 쿼리를 실행하는 것이다. 아래는 JDBC 스펙에 적혀 있는 문구다.

"The tables provided here describe the various mappings and conversions that drivers must support"

 

MySQL

예를 들어, java의 boolean은 BIT나 BOOLEAN으로 변환되고, MySQL은 이 BIT나 BOOLEAN을 MySQL 서버에서 사용하는 TINYINT로 변환하는 것이다.

 

 


3. MyBatis도 마찬가지 원리다.

그림 클릭 시 링크 이동

MyBatis는 내부적으로 타입 헨들러(Type Handler)가 있는데, 이것이 xml에 적힌 SQL문에 전달되는 데이터형을 해석하고 알맞은 JDBC 타입으로 변환한다. 

예를 들어, java 타입으로 boolean이 들어오면, BooleanTypeHandler가 이 데이터를 JDBC의 BOOLEAN 데이터로 변환한다. 이 데이터를 각자가 사용하는 DB의 드라이버들이 자신들의 서버에 맞는 데이터로 변환해 쿼리를 수행하는 것이다.

 

 


4. 응용

근본적으로 자바 애플리케이션과 데이터베이스는 서로 다른 시스템에 속하는 서로 다른 프로그램이다. 데이터 타입도 다르다. 따라서 자바 애플리케이션은 자신만이 알고 있는 데이터 타입(java.lang 패키지 데이터들과 각종 자바 표준 라이브러리 객체들)이 정말로 데이터베이스와 연동될 수 있는지 검증하고 파악하는 것이 중요하다.

예를 들어, java의 LocalDate 객체는 MyBatis와 MySQL 드라이버를 통해 MySQL의 date 데이터 타입에 입력할 수 있을까?

마이바티스 타입 핸들러 항목 중 LocalDate 부분

마이바티스의 타입 핸들러를 보면 java.time.LocalDate를 JDBC의 DATE 타입으로 설정해준다고 나와 있다.

MySQL JDBC 변환표

또한 JDBC의 DATE 타입은 MySQL의 date 타입으로 변환이 된다. 즉, LocalDate 객체는 걱정없이 자유롭게 마이바티스와 MySQL jdbc driver로 사용할 수 있는 것이다.

 

반대로 사용할 수 없는 타입도 발견해 문제를 해결할 수도 있다. MyBatis가 아니라 JDBC를 그대로 사용한다고 해보자. JDBC 데이터 타입을 보면 LocalDate는 항목이 없다!! 대신 java.sql.DATE 항목이 있다. (테이블을 보라) 따라서 LocalDate 타입으로 도메인 로직을 처리하고 있다면, DB 처리를 할 때는 이것을 java.sql.DATE 항목으로 변환해야 하는 것이다.