노트

JDBC와 JdbcTemplate

JDBC (Java Database Connectivity) and JdbcTemplate

백엔드#spring#db · 연결된 개념 4개

쉽게 말하면

JdbcTemplate은 DB에 쿼리할 때마다 연결 열기, 결과 넘겨보기, 예외 처리, 뒷정리 같은 반복 일을 대신해 주는 집사 같아요. 나는 어떤 SQL을 보낼지와 결과 한 줄을 어떤 객체로 받을지만 정하면 되죠.

비유가 깨지는 곳 집사가 SQL까지 대신 짜 주진 않아요. SQL은 여전히 직접 쓰고, 값은 문자열로 이어 붙이지 말고 파라미터로 바인딩해야 SQL 주입을 막아요. 객체로 다루는 다음 단계가 JPA예요.

JDBC(Java Database Connectivity)는 자바가 여러 DB와 통신하기 위한 표준 API이고, Hibernate·MyBatis·스프링 JDBC 모두 그 위에 있다. JdbcTemplate은 스프링이 JDBC의 반복 작업(연결 열고 닫기, 예외 변환, 결과 순회)을 대신해 주는 클래스다.

순수 JDBC가 번거로운 이유

드라이버 로드 → Connection 얻기 → Statement 준비 → 실행
→ ResultSet 순회 → 예외 처리 → ResultSet·Statement·Connection 닫기

매 쿼리마다 이 보일러플레이트를 쓰고, 체크 예외(checked exception)를 직접 처리하고, 닫는 것을 깜빡하면 연결이 샌다. SQL에 DB 방언(dialect)이 섞이면(MySQL LIMIT vs Oracle FETCH FIRST) DB를 바꿀 때 전부 고쳐야 한다.

JdbcTemplate이 맡는 것

개발자는 SQL, 파라미터, 행 하나를 객체로 바꾸는 방법만 정한다. 연결 관리, 실행, 순회, 예외 변환(DataAccessException), 트랜잭션 참여, 자원 정리는 스프링이 한다.

public List<Contact> findOpen() {
    return jdbc.query("SELECT id, name, status FROM contact WHERE status = ?",
        (rs, rowNum) -> new Contact(rs.getLong("id"), rs.getString("name"), rs.getString("status")),
        "OPEN");
}
 
int updated = named.update(
    "UPDATE contact SET status = :status WHERE id = :id",
    Map.of("status", "CLOSED", "id", id));
  • RowMapper: ResultSet의 한 행을 객체로 바꾸는 함수. 컬럼명과 필드명이 같으면 BeanPropertyRowMapper나 DataClassRowMapper를 쓴다
  • NamedParameterJdbcTemplate: ? 대신 :이름 자리표시자. 파라미터가 많을 때 순서 실수를 막는다
  • 파라미터 바인딩은 SQL 주입(SQL injection)을 막는다. 문자열 결합으로 SQL을 만들지 않는다
  • 스레드 안전해서 빈 하나를 여러 DAO(Data Access Object)가 공유한다. 스프링 부트는 DataSource와 함께 자동으로 만든다
  • 스프링 6.1부터는 플루언트 API인 JdbcClient도 있다(2026 기준)

H2

자바로 만든 인메모리 DB라 테스트·PoC(Proof of Concept)에 쓴다. 스프링 부트는 클래스패스에 H2가 있으면 자동으로 연결하고, schema.sql·data.sql로 시작 시 테이블과 데이터를 만든다. 웹 콘솔(/h2-console)도 켤 수 있다. 재시작하면 데이터가 사라지고 방언이 운영 DB와 달라, 운영과 같은 DB를 컨테이너로 띄우는 테스트(Testcontainers)가 더 믿을 만하다.

SQL을 직접 쓰지 않고 객체로 다루는 다음 단계는 Spring Data 리포지터리와 쿼리 메서드와 JPA다. 오라클 저장 프로시저 호출은 Oracle PL/SQL을 본다.

출처: Spring Framework 문서: JdbcTemplate · NamedParameterJdbcTemplate · JdbcClient

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • Lombok

    Lombok은 게터·세터·생성자·toString 같은 반복 코드를 어노테이션으로 대신 생성해 주는 자바 라이브러리다. 컴파일할 때 어노테이션 처리기(annotation processor)가 바이트코드(bytecode)에 메서드를 넣는다. 스프링과는 별개 라이브러리라 따로 추가한다.

  • 의존성 주입 (DI)

    객체가 필요한 협력 객체를 직접 new로 만들지 않고, 바깥(스프링 컨테이너)에서 넣어 받는 방식. 무엇을 언제 만들고 어떻게 연결할지의 제어가 내 코드에서 컨테이너로 넘어가므로 제어의 역전(Inversion of Control, IoC)이라고도 부른다.

  • DB 인덱스와 트레이드오프

    DB 인덱스는 특정 컬럼 값으로 행을 빨리 찾도록 테이블 옆에 따로 유지하는 보조 자료구조(auxiliary data structure)다. 관계형 DB의 기본 인덱스는 정렬된 균형 트리(B-tree 계열)라서, 전체를 훑지 않고 트리를 따라 내려가 원하는 행에 닿는다.

  • 템플릿 메서드 패턴

    알고리즘의 뼈대(단계의 순서)는 상위 클래스의 메서드에 고정하고, 일부 단계만 하위 클래스가 바꾸게 하는 패턴.

  • 데이터 무결성

    데이터 무결성(data integrity)은 저장된 데이터가 정확하고 일관되며 믿을 수 있는 상태로 유지되는 것이다. 재고가 100개로 보이는데 실제로 50개라면 무결성이 깨진 것이다. 관계형 DB는 이를 제약 조건(constraint)으로 강제한다.

보기 옵션