JDBC Connection과 DataSource

헙크·2023년 4월 18일
2

데이터베이스

목록 보기
1/1
post-thumbnail

0. 개요

이번 글에서는 JDBC Connection과 DataSource에 대해서 알아보고자 하였습니다. 추가적으로 DriverManager에 대해서도 정리해봤습니다. 프레임워크적으로 이들을 사용하기 이전에 이것들이 왜 추상화되었는지, 그렇게 하였을 때 어떤 이점이 있는지를 중점으로 알아보았습니다.

1. DB Connection

1.1. DB Connection이란 무엇인가?

커넥션이란 애플리케이션과 데이터베이스 서버 간의 통신 링크를 의미합니다. 애플리케이션이 쿼리를 실행하고 데이터를 검색하고, 데이터베이스에서 트랜잭션을 수행할 수 있는 세션을 설정하는 데에 사용됩니다. 자바 진영에서의 커넥션은 자바 애플리케이션이 표준화된 방식으로 관계형 데이터베이스와 상호 작용할 수 있도록 하는 JDBC(Java Database Connectivity) API에 의해 관리됩니다.

1.2. Connection은 어떻게 동작하는가?

다음은 DB의 커넥션을 얻기 위한 일련의 동작 과정입니다.

  1. JDBC 드라이버 로드

    애플리케이션은 커넥팅해야 하는 특정 데이터베이스에 적합한 JDBC 드라이버를 로드합니다.

  2. 커넥션 세부 정보 제공

    애플리케이션이 데이터베이스 URL, 사용자 이름 및 암호와 같은 필요한 커넥션 세부 정보를 준비합니다.

  3. 커넥션 설정

    JDBC 드라이버는 제공된 정보를 사용하여 데이터베이스 서버에 대한 연결을 시도합니다. 인증에 성공하면 서버에서 액세스 권한을 부여하고 커넥션 객체가 생성됩니다.

  4. 커넥션 사용

    애플리케이션은 커넥션 객체를 사용하여 SQL 쿼리 실행, 트랜잭션 관리 및 메타데이터 검색과 같은 데이터베이스에서 다양한 작업을 수행합니다.

  5. 커넥션 풀링(선택적)

    성능 및 리소스 활용도를 개선하기 위해 커넥션 풀을 사용할 수 있습니다. 응용 프로그램은 커넥션을 자주 만들고 커넥션을 닫는 대신 풀에서 커넥션을 만들어 놓고 사용 후 반납하는 방식입니다.

  6. 커넥션 닫기

    애플리케이션이 더 이상 커넥션을 필요로 하지 않으면 리소스를 확보하기 위해 커넥션을 닫습니다. 커넥션 풀링의 경우 커넥션의 재사용을 위해 풀로 반환됩니다.

2. JDBC Connection

2.1. JDBC Connection이란?

JDBC 커넥션이란 자바에서 제공하는 표준 커넥션 API입니다. 이를 사용해 위에서 설명했던 커넥션이 수행해야할 일련의 동작들을 수행할 수 있습니다.

유의해야할 것은 JDBC Connection은 인터페이스로 정의되어 있다는 것입니다. 여러 벤더사들의 드라이버는 자신들의 커넥션을 클라이언트에게 제공할 때, 자신들이 만든 구체적인 구현체가 아닌 Connection을 구현한 구현체를 제공할 것입니다.

이로써 클라이언트는 어떤 드라이버를 사용하더라도, 그저 Connection이라는 인터페이스만 의존하고 있으면 되므로 드라이버가 변경되더라도 클라이언트는 수정되지 않아도 됩니다.

이 부분에서 DIP와 OCP를 만족하는 전략 패턴이 사용되었다고 볼 수 있습니다.

2.2. JDBC Connection 내부 구현

위와 같이 인터페이스로 정의되어 있습니다.

Connection 인터페이스의 구현체는 위처럼 h2관련 구현체들이 있는 것을 확인할 수 있습니다.

이는 우리가 build.gradle 파일에 runtimeOnly 'com.h2database:h2’로 데이터베이스의 의존성을 추가해주었기 때문에 자동적으로 생긴 것으로 보입니다.

이처럼 우리는 Connection을 사용하기만 하면, 추후에 Oracle 혹은 MySQL 등의 DB 드라이버로 바꾸더라도 기존 코드는 변경하지 않고 변경 가능합니다.

2.3. Trouble Shooting

맨 위쪽의 Connection에 대해서 설명할 때, 커넥션 풀링에 대해서 언급한 적이 있습니다. 이는 커넥션을 미리 여러 개 만들어 놓고 커넥션이 필요할 때마다 이 풀에 있는 커넥션을 하나씩 사용하고, 모두 사용한 후에는 커넥션을 닫는 것이 아니라 다시 풀에 반환하도록 하는 기술입니다.

만약 커넥션을 얻어오는 방식을 변경하고 싶다면, 기존 코드를 변경해야 하지 않을까요?! 변경해야 하는 구조라면 OCP를 만족하지 않는 상황이 발생할 것 같습니다. 어떻게 하면 될까요!?

이제 DataSource에 대해서 알아보는 것이 좋을 것 같습니다 :)

3. DataSource

3.1. DataSource란?

DataSource는 Connection을 얻어오는 방법을 추상화한 것입니다. 이 부분에서도 전략 패턴을 사용한 것을 확인할 수 있습니다. 여러 구현체를 기존 코드의 변경 없이 변경 가능하도록 하였습니다.

3.2. DataSource 내부 구현

이 또한 인터페이스이기에, 여러 하위 구현체를 가질 수 있습니다.

위는 DataSource의 구현체의 일부입니다. DriverManagerDataSource는 스프링에서 제공하고 있고, JdbcDataSource는 h2에서 제공하고 있네요. 또한 HikariDataSource를 사용하면 커넥션 풀을 사용할 수 있습니다. HikariCP는 유명한 커넥션 풀 라이브러리입니다.

3.3. 중간 정리

위의 Connection과 DataSource의 구조를 도식화하면 다음과 같습니다.

3.4. Trouble Shooting

이전에 순수 JDBC를 활용해 개발을 진행했을 때, 커넥션을 얻어오는 부분에서 DriverManager를 사용했던 적이 있습니다(우테코 레벨1의 체스게임). 그렇다면 DriverManager는 무엇이고, 왜 위의 도식화된 그림에는 존재하지 않는 것일까요?

4. DriverManger

4.1. DriverManager란?

DriverManager 또한 기본적으로 커넥션을 얻어오는 역할을 하는 클래스입니다.

4.2. 내부 구현

내부 구현 코드는 다음과 같습니다.

뭔가 이상하지 않으신가요?! DataSource처럼 인터페이스도 아니고, DataSource를 구현한 구현체도 아닙니다. 그저 일반적인 클래스로 다음과 같이 커넥션을 얻어오는 static 메서드를 제공합니다.

4.3. DriverManager vs DataSource

정리하자면 DriverManager와 DataSource는 모두 JDBC API를 사용하여 Java에서 데이터베이스 Connection을 설정하고 사용하는 데에 사용됩니다.

DriverManager는 더 단순하고 오래된 접근 방식으로, 일종의 유틸 클래스라고 볼 수 있습니다. DIP와 OCP도 만족하지 않는 그저 유틸 클래스이므로 강하게 결합이 되어 있어, 커넥션을 얻어오는 방법 등이 변경되었을 때 클라이언트 코드 수정이 불가피할 것입니다.

반면 DataSource는 커넥션을 얻어오는 방법을 추상화한 인터페이스이고, 하위에 여러 구현체를 가지기 때문에 여러 구현체를 바꿔가면서 클라이언트 코드를 변경할 필요가 없다는 장점을 취할 수 있습니다.

따라서 간단하게 커넥션을 얻어와 사용하는 때에는 DriverManager를 사용해도 좋지만, 실제 프로젝트를 진행한다거나 실무에서는 DataSource를 사용하는 것이 좋을 것 같습니다.

5. 결론

  1. JDBC Connection : 커넥션 객체를 추상화한 것이다. 드라이버가 달라지더라도 클라이언트는 영향을 받지 않는다.

  2. DataSource : 커넥션을 얻어오는 방법을 추상화한 것이다. 커넥션을 관리하는 방법이 달라지더라도 클라이언트는 영향을 받지 않는다.

    (DriverManager는 간단하게 커넥션을 얻을 수 있도록하는 유틸 클래스이다)

1개의 댓글

comment-user-thumbnail
2023년 4월 18일

쿠울~

답글 달기