Post

JDBC와 커넥션

JDBC (Java Database Connectivity)

자바 애플리케이션과 데이터베이스 사이의 통신을 가능하게 하는 API

jdbc.png

자바 애플리케이션에서 데이터베이스에 접근하기 위해 JDBC API를 이용해서 데이터베이스에 접근하고, JDBC API는 JDBC 드라이버를 거쳐 데이터베이스와 통신한다.


특징

  • 플랫폼에 독립적입니다.
    Java 언어가 실행될 수 있는 모든 플랫폼에서 동일한 방식으로 데이터베이스를 접속하고 관리할 수 있다.

  • 데이터베이스 연결, 쿼리 실행, 결과 처리의 과정을 통합적으로 지원하여, 접속 과정을 단순화할 수 있다.

  • 다양한 DBMS와 호환된다.

  • SQL을 사용해서 데이터베이스와 상호작용한다.

  • 트랜잭션을 지원하여 데이터베이스 작업의 일관성을 유지할 수 있으며 하나의 트랜잭션으로 묶어 실행하거나 롤백할 수 있다.




JDBC가 생긴 이유?

Java 애플리케이션이 다양한 데이터베이스와 상호작용할 수 있도록 표준화된 방법을 제공하기 위해 생겼다.

데이터베이스 연결, 쿼리 실행, 결과 처리 등의 과정을 통일된 API로 간편하게 처리할 수 있게 하여,
데이터베이스의 독립성과 통합된 접근 방식을 제공한다.


JDBC 드라이버

1) DBMS와 통신을 담당하는 자바 클래스

2) DBMS별로 알맞는 JDBC 드라이버가 필요하다

3) 로딩 코드 : Class.forName(“JDBC드라이버 이름”);

  • 오라클 : oracle.jdbc.driver.OracleDriver
  • Mysql : com.mysql.cj.jdbc.Driver


JDBC URL

1) DBMS와 연결을 위한 식별 값

2) JDBC 드라이버에 따라 형식이 다르다

3) 구성 : jdbc:[DBMS]:[데이터베이스식별자]


Class.forName() 동작 원리

주로 JDBC에서 데이터베이스 드라이버를 동적으로 로드하기 위해 사용한다.
이 메서드를 통해 특정 클래스를 JVM의 클래스 로더에 로드한다.

Class.forName() 메소드에 Driver 클래스 위치를 넘겨줄 뿐, 리턴 값을 받는 등의 아무런 동작이 없다.

Class.forName()을 호출해 드라이버 클래스를 로드하면, 해당 클래스는 자신을 DriverManager에 등록한다.
하지만, 이 시점에서 데이터베이스와의 연결은 일어나지 않는다.

이후 DriverManager.getConnection()을 호출하면, 실제로 데이터베이스와의 연결을 생성한다.
getConnection() 메소드는 등록된 JDBC 드라이버들 중에서 적절한 드라이버를 찾아 데이터베이스 연결을 시도한다.


이후 DriverManager.getConnection()을 하면 해당 연결 객체를 넘겨주는 이유

Class.forName()은 단순히 드라이버 클래스를 JVM에 로드하는 역할을 하고,
데이터베이스와의 연결을 생성하는 것은 DriverManager.getConnection() 이 합니다.


JDBC 사용법

  • Class.forName() : 드라이버를 로드한다.
  • DriverManager : 로드된 드라이버를 통해서 Connection을 활성화해주는 객체
  • Connection : 데이터베이스와의 연결
  • Statement : SQL을 실행하는 객체
  • ResultSet : SQL문 실행 후 데이터를 받는 객체
  • close() : 자원 반환은 반드시 이루어져야한다.

자바에서는 JDBC를 사용하게되면 DBMS 벤더에 의존하지 않는 독립적인 시스템 개발을 할 수 있다.

이를 통해, DBMS의 종류에 따라 다르게 코딩하지 않고, 어떤 DBMS든지 동일하게 데이터베이스의 CRUD를 구현할 수 있다.




커넥션 풀

데이터 베이스를 연결하려면 네트워크 연결, 인증, 권한 확인 등 여러 단계를 거쳐야 하기 때문에 상당히 많은 리소스를 소모합니다.

이러한 문제를 해결하기 위해 커넥션 풀이 사용됩니다.

커넥션 풀은 미리 일정 수의 연결을 생성해두고 필요할 때마다 연결을 재사용하는 방식입니다. 이를 통해서 연결을 생성하는데 드는 비용을 절감하고 애플리케이션의 성능을 향상시킬 수 있습니다.


커넥션 객체를 생성하는 과정

1. JDBC 드라이버를 메모리에 로드합니다.

1
Class.forName("com.mysql.cj.jdbc.Driver");


2. 데이터베이스와의 연결을 위한 URL을 정의합니다.

1
String url = "jdbc:mysql://localhost:3306/database";


3. 데이터베이스에 접속할 사용자 이름과 비밀번호를 설정합니다.

1
2
String user = "username";
String pasasword = "password";


4. getConnection을 통해 데이터베이스와 연결을 생성하고 연결 과정에서 발생할 수 있는 예외를 처리합니다.

1
Connection connection = DriverManager.getConnection(url, user, password);


5. 연결을 사용한 후 close() 메서드 호출을 통해 연결을 종료합니다.

1
2
3
4
5
6
7
8
9
finally {
    if (connection != null) {
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

-> DB에 연결할 때마다 Connection 객체를 새로 만드는 것은 비용이 많이 들며, 비효율적이다.

이 문제를 해결하기 위해 커넥션 풀이 등장




동작

connectionpool.png

프로그램이 시작하는 시점에서 연결이 미리 생성이 된다.
이 연겯을 풀에 저장해두고 연결이 필요할 때마다 커넥션 풀에 미리 생성해둔 연결을 가져와서 사용한다.

사용이 끝난 연결은 다시 풀에 반환되어 재사용한다.

이 과정에서 데이터베이스 연결의 생성과 소멸이 최소화되기 때문에, 비용을 절감할 수 있으며 효율적이다.

풀의 크기가 너무 작은 경우 사용 가능한 연결이 부족해 성능 저하가 발생할 수 있으며, 반대로 풀의 크기가 너무 큰 경우 불필요하게 많은 리소스를 소모한다.




커넥션 풀의 구현 방법

커넥션 라이브러리 : Apache DBCP, C3P0, HikariCP 등이 있으며, 스프링 부트 2.3 이상에서는 기본 커넥션 풀로 HikariCP가 설정되어 있습니다.

1
2
3
4
5
6
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
config.setUsername("user");
config.setPassword("password");
config.setMaximumPoolSize(10);
HikariDataSource dataSource = new HikariDataSource(config);

커넥션 풀 라이브러리를 사용하여 개발자는 데이터베이스 연결 관리의 복잡성을 줄이고 애플리케이션 성능을 향상시킬 수 있다.

커넥션 풀 라이브러리는 풀의 상태를 모니터링할 수 있는 기능을 제공하며, 이를 통해 풀의 사용률, 연결 대기시간, 활성 연결 수 등 다양한 지표를 실시간으로 확인할 수 있다.

또한 요구 상황과 리소스 상황에 맞춰 커넥션 풀의 설정을 조정함으로써 최적의 성능을 달성할 수 있다.

단점으로는 DB에서 정보를 가지고 올 때마다 DB Connection Disconnection을 해야하고, 서버 과부하 및 속도 저하의 문제가 있다.

This post is licensed under CC BY 4.0 by the author.