[JDBC] db Connection

컨테이너·2025년 11월 10일
0

SpringFramework

목록 보기
1/15
post-thumbnail

Java JDBC DB Connection 정리

이 글은 직접 작성한 콘솔 프로젝트의 예시 코드를 바탕으로, Java에서 JDBC로 데이터베이스에 연결하는 방법과 안전한 구현 패턴을 정리한다. 사용 DB는 MariaDB이며, 다른 JDBC 드라이버로도 원리는 동일하다.

1. JDBC 한 줄 요약

JDBC는 Java 애플리케이션이 데이터베이스에 접근하기 위한 표준 API다. 애플리케이션은 JDBC 드라이버를 통해 커넥션을 열고, SQL을 전송하고, 결과를 받아 처리한다.

2. . 코드: DBCon

가장 핵심은 커넥션을 얻는 부분이다. 아래와 같은 형태로 작성한다.

package dbconnection;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBCon {
    private static Connection conn;

    public static Connection getConnection() throws SQLException {
        String url = "jdbc:mariadb:/.../...";
        String user = "root";
        String password = "password1";

        if (conn == null) {
            conn = DriverManager.getConnection(url, user, password);
        }
        return conn;
    }
}

3. 애플리케이션: Run

애플리케이션 진입점에서는 예외를 처리하고, 종료 훅에서 커넥션을 정리하면 안정적이다.

package run;

import controller.Controller;
import dbconnection.DBCon;
import view.View;

public class Run {
    public static void main(String[] args) {
        try {
            // 최초 연결 (실제로는 DAO/Service에서 필요 시 얻어도 된다)
            DBCon.getConnection();

            Controller controller = new Controller();
            View view = new View(controller);

            // 종료 시 커넥션 정리
            Runtime.getRuntime().addShutdownHook(new Thread(DBCon::closeConnection));

            view.mainmenu();
        } catch (Exception e) {
            System.err.println("[FATAL] 앱 시작 실패: " + e.getMessage());
            e.printStackTrace();
            DBCon.closeConnection();
        }
    }
}

4. JDBC에서 Singleton 패턴을 사용하는 이유

JDBC로 데이터베이스에 연결할 때 가장 중요한 것은 Connection 객체의 관리이다.

매번 새로운 커넥션을 생성하면 비용이 크고, 너무 많은 커넥션이 동시에 열리면 데이터베이스 자원을 과도하게 점유하게 된다.

이 문제를 방지하기 위해 Singleton 패턴(Single Instance Pattern) 을 사용하는 경우가 많다.


1. Singleton 패턴이란

Singleton은 클래스의 인스턴스를 오직 한 개만 생성하도록 보장하는 디자인 패턴이다.

전역에서 동일한 인스턴스(객체)에 접근할 수 있게 하되, 중복 생성을 방지한다.

JDBC에서 이를 적용하면, 애플리케이션 전역에서 하나의 DB 커넥션 인스턴스를 공유하는 구조가 된다.

2. JDBC에서 Singleton을 사용하는 이유

(1) 커넥션 생성 비용 절감

DriverManager.getConnection() 은 내부적으로 네트워크 소켓 연결, 인증, 세션 초기화 등의 과정을 거친다.

이 작업은 매우 느리고 비용이 크다.

  • Singleton을 사용하면 커넥션을 한 번만 생성하고, 이후에는 동일한 커넥션을 재사용할 수 있어 효율적이다.

예시

Connection conn1 = DBCon.getConnection();
Connection conn2 = DBCon.getConnection();
System.out.println(conn1 == conn2); // true → 동일 객체

이렇게 하나의 인스턴스를 재사용하면 매 호출마다 새로운 세션을 열지 않아도 된다.

(2) 데이터 일관성 유지

한 애플리케이션 내에서 여러 커넥션이 동시에 열리면,

트랜잭션 범위나 커밋/롤백 단위가 서로 달라질 수 있다.

Singleton을 사용하면 항상 같은 Connection을 참조하므로,

같은 트랜잭션 컨텍스트 내에서 일관된 데이터 작업을 수행할 수 있다.

예를 들어 다음과 같은 시나리오를 생각해 보자.

UserDAO.save(user);
OrderDAO.save(order);

각 DAO가 서로 다른 커넥션을 쓴다면,

한쪽은 커밋되고 다른 쪽은 실패할 수 있다.

하지만 Singleton으로 같은 커넥션을 공유하면,

트랜잭션을 한 번에 관리할 수 있다.

(3) 자원 관리 단순화

DB 커넥션은 한정된 시스템 자원이다.

커넥션을 여러 개 만들고 닫지 않으면 “Too many connections” 에러가 발생한다.

Singleton으로 커넥션을 한 개만 유지하면,

다음과 같은 자원 관리가 쉬워진다.

  • 커넥션을 한 번만 닫으면 됨 (closeConnection())
  • 프로그램 종료 시 안전하게 자원 회수 가능
  • 메모리 릭이나 연결 누수 방지

(4) 전역 접근성 확보

DBCon.getConnection() 형태로

프로젝트의 어디서나 동일한 DB 연결 객체에 접근할 수 있다.

다른 클래스에서 매번 new 로 생성할 필요가 없고, 코드가 단순해진다.


3. Singleton 사용 시 주의점

(1) 커넥션 만료 문제

DB 서버 설정에 따라 일정 시간(Idle Timeout) 후 연결이 끊길 수 있다.

이때는 기존 커넥션이 isClosed() 상태인지 검사하고

필요 시 새로 생성하는 로직을 넣어야 한다.

if (conn == null || conn.isClosed()) {
    conn = DriverManager.getConnection(url, user, password);
}

(2) 멀티스레드 환경

웹 서버나 멀티스레드 환경에서 Singleton은 Thread-safe 해야 한다.

한 스레드가 커넥션을 사용 중일 때 다른 스레드가 접근하면 충돌이 생긴다.

이 문제는 일반적으로 Connection Pool(HikariCP, DBCP) 으로 해결한다.

즉, 콘솔 기반 단일 사용자 프로그램에서는 Singleton으로 충분하지만,

동시 접속이 가능한 서버 환경에서는 커넥션 풀을 써야 한다.


(3) 커넥션은 영원히 유지되지 않는다

프로그램이 오래 실행되면 커넥션이 비정상적으로 끊길 수 있다.

따라서 close() 이후에는 null 처리 후,

필요할 때 다시 연결하는 방식이 필요하다.


4. Singleton 패턴 적용 예시 요약

public class DBCon {
    private static Connection conn;
    private static final String URL = "jdbc:mariadb://localhost:3306/test";
    private static final String USER = "root";
    private static final String PASSWORD = "1234";

    private DBCon() {}

    public static Connection getConnection() throws SQLException {
        if (conn == null || conn.isClosed()) {
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
        }
        return conn;
    }

    public static void closeConnection() {
        try {
            if (conn != null && !conn.isClosed()) {
                conn.close();
                conn = null; // 다음 호출 시 새로 연결
            }
        } catch (SQLException e) {
            System.err.println("DB Close Error: " + e.getMessage());
        }
    }
}

5. 결론

JDBC에서 Singleton을 사용하는 이유는

  1. 커넥션 생성 비용 절감
  2. 데이터 일관성 유지
  3. 자원 관리 단순화
  4. 전역 접근성 확보

등이 있다. 다만, 이 방식은 단일 사용자 환경(콘솔, 간단한 데스크톱 프로그램) 에 적합하다.

서버 환경에서는 Connection Pool 을 사용하는 것이 훨씬 안전하고 효율적이다.


요약

구분Singleton 사용 이유
성능커넥션 재사용으로 생성 비용 절감
안정성트랜잭션 일관성 유지
자원 관리커넥션 누수 방지, 관리 단순화
코드 구조전역 접근, 간결한 호출 구조

JDBC 프로젝트의 초반 단계에서는 Singleton이 가장 단순하고 효과적인 커넥션 관리 방식이다.

하지만 애플리케이션이 커지고 동시에 여러 스레드가 접근하게 되면, Connection Pool로 넘어가는 것이 훨씬 안정적이다.

profile
백엔드

0개의 댓글