JDBC Driver와 Hibernate Dialect

하루히즘·2021년 5월 3일
1

Spring Framework

목록 보기
2/15

서론

지난 스프링 부트 애플리케이션 배포 #2에서 언급했듯이 application properties에 hibernate.dialect가 설정되지 않아 데이터베이스 연결이 정상적으로 이루어지지 않았던 적이 있다.

Thorben Janssen이라는 사람의 글에 따르면 Hibernate는 JDBC 커넥션으로 dialect를 유추할 수 있다고 한다. 하지만 아직 어째서 로컬 환경과 달리 Heroku 환경에서는 직접 dialect를 설정해줘야 하는 지 파악하진 못했다. 하지만 관련 내용을 조사하다보니 JPA, 정확히는 Spring Data JPA의 Hibernate를 사용할 때는 애플리케이션에서 사용하는 데이터베이스의 종류에 맞게 dialect를 설정해주는 것이 보편적이라고 한다.

그래서 datasource와 Hibernate의 Dialect에 대해서 간략하게 조사해 보았다.

본론

DataSource, DriverManager

자바에서는 데이터베이스에 접근하는 가장 기본적인 방법으로 DataSource, DriverManager가 있다. 기존에 자바 애플리케이션을 이용하여 데이터베이스에 접근해본 적이 없다면 처음 보는 클래스/인터페이스일 텐데 먼저 DataSource는 javax.sql 패키지에 포함된 인터페이스다.

이 인터페이스에서는 데이터베이스 서버에 연결해서 커넥션을 얻어오고 커넥션 풀을 구현하는 역할을 정의하고 있으며 데이터베이스 제조사에 의해 구현된다.

비슷하게 데이터베이스를 활용하기 위해 정의된 클래스로 DriverManager가 있다. 스프링 데이터베이스 접근 예제 코드에서 단골로 등장하며 getConnection 메서드를 이용하여 커넥션을 얻어오는 클래스로 JDBC 4.0 이전까지는 데이터베이스 접근에 사용할 JDBC 드라이버를 수동으로 불러와야 했지만 4.0 이후부터는 지정된 경로의 드라이버들을 자동으로 불러온다.

최근에는 DataSource 인터페이스를 구현한 클래스를 사용하는 것이 권장되지만 둘 중 어느 방법을 사용하더라도 동일한 데이터베이스 커넥션을 얻어올 수 있다. 가장 큰 차이점은 DataSource는 JNDI를, DriverManager는 데이터베이스 서버 주소, 포트, 사용자 이름, 비밀번호 등 다양한 정보가 필요하다는 것이다. 보통 실습에서는 후자를 활용한다. 둘의 차이는 스택오버플로우의 글을 참고하면 좋다.

application.properties

스프링에서는 이를 어떻게 활용하여 데이터베이스에 접근하고 있을까? 스프링은 프레임워크답게 관련 Bean 객체나 설정만 등록된다면 자동으로 커넥션 획득, SQL 실행, 예외처리 등 반복적이고 개발 외적인 다양한 작업을 대신 처리해준다.

대개 데이터베이스에 접근할 때는 호스팅 받은(또는 개인) 서버 주소, 사용자 이름, 비밀번호, 포트 번호 등을 받아서 접근하기 때문에 DataSource보다는 DriverManager 쪽으로 설정하게 된다. 유의할 점은 스프링 부트에서는 둘 중 하나만 사용할 수 있다.

부트가 아닌 일반 스프링 프레임워크에서는 datasource 패키지의 클래스의 Bean 객체에 속성값을 부여하여 등록하거나 JPA를 사용한다면 persistence.xml 파일에서 설정해줘야 했다. 그러나 스프링 부트에서는 application properties 파일에 다음처럼 데이터베이스 접근 정보를 적어주기만 하면 간편하게 설정할 수 있으며 이 방법을 자주 사용한다.

spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=${JAWSDB_MARIA_URL}
spring.datasource.username=${JAWSDB_MARIA_USERNAME}
spring.datasource.password=${JAWSDB_MARIA_PASSWORD}

데이터베이스 접근을 위해 리소스 파일에 설정하는 값은 크게 위의 4가지다. url은 JDBC URL(i.e. jdbc://localhost:3306/dbname), username은 데이터베이스 계정 이름, password는 데이터베이스 계정 비밀번호를 입력하면 된다.

중요한 것은 spring.datasource.driver-class-name이다. 스프링 문서에서는 이 속성값을 다음과 같이 정의하고 있다.

Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.

이 속성에 사용할 JDBC 드라이버의 이름을 부여하면 애플리케이션에서 데이터베이스에 연결할 때 해당 이름의 JDBC 드라이버를 찾아서 사용하게 된다.

JDBC Driver

그럼 이 JDBC Driver는 무엇일까? 위키피디아에서는 다음과 같이 정의하고 있다.

A JDBC driver is a software component enabling a Java application to interact with a database.

즉 자바 애플리케이션이 특정 벤더의 데이터베이스와 상호작용할 수 있도록 해주는 소프트웨어 구성 요소다. '드라이버'라는 이름 그대로 다양한 제조사의 다양한 데이터베이스 제품을 사용할 수 있도록 도와주는 역할이며 데이터베이스에서 커넥션을 얻어오고 클라이언트와 서버 간 통신 프로토콜을 구현한다.

간단하게 말하면 자바 언어를 사용하여 데이터베이스와 통신하기 위해 필수적으로 요구되는 중간 장치라고 생각하면 된다.

Hibernate Dialect

그런데 애플리케이션에서는 JDBC Driver 뿐 아니라 Hibernate Dialect도 설정했다. 이 dialect란 것은 왜 필요한 것일까? 이는 기본적으로 JPA를 왜 사용하는지를 생각하면 쉽게 이해할 수 있다.

JPA는 데이터베이스를 활용하는 자바 애플리케이션을 개발할 때 SQL 쿼리를 작성하는 시간을 줄이고 객체지향적으로 코드를 작성할 수 있도록 하기 위해 사용한다. 이는 개발자들이 데이터베이스 테이블 기반 SQL 중심 개발이 아니라 객체지향 패러다임 기반 엔티티 클래스 중심으로 개발할 수 있도록 하는데 그럼 쿼리는 어떻게 되는 걸까?

어쨌든 데이터베이스에 명령을 실행하려면 쿼리를 작성해서 실행해야 한다. 이 쿼리 작성을 대신 해주는게 JPA(Hibernate)고 쿼리를 작성하기 위해 필요한 것이 Hibernate의 Dialect인 것이다.

데이터베이스의 쿼리는 서로 유사하게 생겼지만 각자 사용할 수 있는 함수나 지원하는 기능에서 차이가 있다. 개발자가 직접 이 차이를 인지하고 SQL 쿼리를 작성하는 것은 번거로운 일이기 때문에 객체 지향 모델을 기반으로 데이터베이스에 맞는 쿼리를 생성해주는 JPA를 사용하는 것이다. 이 경우 JPA가 어떤 데이터베이스에 맞는 쿼리를 생성할 것인지 dialect를 설정해줘야 하는 것은 당연할 것이다.

역시 스프링 부트에서는 application.properties에 작성해 줄 수 있으며 다음처럼 설정해주면 된다. 이때 애플리케이션에서 참조하는 데이터베이스에 맞는 dialect를 조사해서 설정해줘야 하며 아래의 예시는 MariaDB의 dialect다.

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect

JDBC Driver, Hibernate Dialect

위의 내용으로 봤을때 결과적으로 JDBC Driver와 Hibernate의 Dialect는 별도의 개념으로 보고 둘 다 각각 설정해주는 것이 좀 더 명확하다고 할 수 있다. 전자는 자바 애플리케이션에서 데이터베이스 솔루션과 상호작용하기 위한 소프트웨어 구성 요소고 후자는 자바 애플리케이션에서 개발자가 SQL 쿼리를 직접 작성하는 대신 클래스와 객체를 이용하여 데이터베이스에 맞는 쿼리를 자동으로 생성하기 위한 필수적인 가이드라인이라 이해하면 될 것이다.

후기

JDBC Driver나 Hibernate의 Dialect는 아예 모르던 개념은 아니지만 언급했듯이 Hibernate의 자동 설정 때문에 데이터베이스 접근과 ORM 매핑을 이용한 SQL 생성을 명확하게 구분하지 못했었다.

그래도 이렇게 한번 정리하고 나면 나중에 잘 구분할 수 있을 것이다.

참고

Working with SQL databases
difference between database drivers and database dialects

profile
YUKI.N > READY?

0개의 댓글