[Spring DB] 스프링 JdbcTemplate

2025. 6. 23. 06:39코딩 도구/백엔드 개발 (Backend Development)

반응형

스프링 JdbcTemplate 정리

이 글은 인프런 김영한님의 "스프링 DB 2편 - 데이터 접근 활용 기술" 강의를 수강하고 정리한 내용이다.


1. JdbcTemplate이란?

JdbcTemplate은 순수 JDBC를 사용할 때 반복되는 코드를 줄여주는 템플릿 콜백 방식의 유틸리티다. spring-jdbc 라이브러리에 포함되어 있으며, 데이터베이스 접근 시 다음과 같은 반복 작업을 대신 처리해준다.

  • 커넥션 획득 및 종료
  • PreparedStatement 준비 및 실행
  • ResultSet 반복 처리
  • 예외 변환 (SQLException → DataAccessException)
// build.gradle 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.h2database:h2'

2. JdbcTemplate 기본 적용 - V1

주요 클래스: JdbcTemplateItemRepositoryV1

public class JdbcTemplateItemRepositoryV1 implements ItemRepository {
    private final JdbcTemplate template;

    public JdbcTemplateItemRepositoryV1(DataSource dataSource) {
        this.template = new JdbcTemplate(dataSource);
    }

    public Item save(Item item) {
        String sql = "insert into item (item_name, price, quantity) values (?, ?, ?)";
        KeyHolder keyHolder = new GeneratedKeyHolder();

        template.update(connection -> {
            PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
            ps.setString(1, item.getItemName());
            ps.setInt(2, item.getPrice());
            ps.setInt(3, item.getQuantity());
            return ps;
        }, keyHolder);

        item.setId(keyHolder.getKey().longValue());
        return item;
    }
    // update, findById, findAll 구현 생략
}
  • RowMapper는 ResultSet을 자바 객체로 변환하는 역할을 한다.
  • queryForObject는 단건 조회, query는 목록 조회에 사용한다.

KeyHolder를 사용하면 DB에서 생성된 PK를 조회할 수 있다.


3. 이름 지정 파라미터 - V2

클래스: JdbcTemplateItemRepositoryV2

NamedParameterJdbcTemplate은 파라미터를 이름으로 바인딩하므로 유지보수성과 안정성이 높다.

String sql = "update item set item_name=:itemName, price=:price where id=:id";
SqlParameterSource param = new MapSqlParameterSource()
    .addValue("itemName", item.getItemName())
    .addValue("price", item.getPrice())
    .addValue("id", itemId);

template.update(sql, param);

주요 파라미터 바인딩 방식

  • Map<String, Object>: 단순하고 빠르게 사용 가능
  • MapSqlParameterSource: SQL 타입 지정 가능, 메서드 체인 지원
  • BeanPropertySqlParameterSource: 자바빈 프로퍼티에서 자동 추출

RowMapper 개선: BeanPropertyRowMapper

private RowMapper<Item> itemRowMapper() {
    return BeanPropertyRowMapper.newInstance(Item.class);
}

DB 컬럼명과 자바 필드명이 다를 경우 SQL에서 별칭(as)을 활용한다.


4. SimpleJdbcInsert 적용 - V3

클래스: JdbcTemplateItemRepositoryV3

this.jdbcInsert = new SimpleJdbcInsert(dataSource)
    .withTableName("item")
    .usingGeneratedKeyColumns("id");

public Item save(Item item) {
    SqlParameterSource param = new BeanPropertySqlParameterSource(item);
    Number key = jdbcInsert.executeAndReturnKey(param);
    item.setId(key.longValue());
    return item;
}
  • SimpleJdbcInsert는 INSERT SQL을 자동 생성해준다.
  • 테이블 메타데이터를 조회해서 사용 가능 컬럼 파악
  • usingColumns를 지정하면 원하는 컬럼만 INSERT 가능

insert SQL을 직접 작성하지 않아도 되고, PK 생성 컬럼도 자동으로 추적해준다.


5. 구성 및 실행

설정 클래스

@Configuration
@RequiredArgsConstructor
public class JdbcTemplateV3Config {
    private final DataSource dataSource;

    @Bean
    public ItemService itemService() {
        return new ItemServiceV1(itemRepository());
    }

    @Bean
    public ItemRepository itemRepository() {
        return new JdbcTemplateItemRepositoryV3(dataSource);
    }
}

실행 설정

spring.profiles.active=local
spring.datasource.url=jdbc:h2:tcp://localhost/~/test
spring.datasource.username=sa
logging.level.org.springframework.jdbc=debug
  • SQL 로그를 확인하려면 logging.leveldebug로 설정한다.

6. JdbcTemplate 기능 요약

JdbcTemplate 순서 기반 파라미터 바인딩
NamedParameterJdbcTemplate 이름 기반 바인딩, 실무에서 추천
SimpleJdbcInsert INSERT SQL 자동 생성
SimpleJdbcCall 저장 프로시저 호출 지원

7. 공식 메뉴얼 요약 예제

// 단건 숫자 조회
int count = jdbcTemplate.queryForObject("select count(*) from t_actor", Integer.class);

// 객체 단건 조회
Actor actor = jdbcTemplate.queryForObject(
    "select first_name, last_name from t_actor where id = ?",
    (rs, rowNum) -> {
        Actor a = new Actor();
        a.setFirstName(rs.getString("first_name"));
        a.setLastName(rs.getString("last_name"));
        return a;
    },
    1212L);

// 목록 조회
List<Actor> actors = jdbcTemplate.query(
    "select first_name, last_name from t_actor",
    (rs, rowNum) -> new Actor(rs.getString("first_name"), rs.getString("last_name"))
);

// INSERT
jdbcTemplate.update("insert into t_actor (first_name, last_name) values (?, ?)", "Leonor", "Watling");

8. 정리

JdbcTemplate은 SQL 중심의 애플리케이션에서 매우 유용하게 사용된다. 다음과 같은 경우 특히 추천된다:

  • SQL을 직접 작성하는 것이 익숙할 때
  • ORM(JPA) 대신 단순하고 명확한 SQL이 필요한 프로젝트
  • JPA와 함께 보조적으로 사용할 때

하지만 동적 쿼리의 경우 복잡한 문자열 조합이 필요하다는 단점이 있다. 이 문제를 해결할 수 있는 기술로는 MyBatisQuerydsl이 존재한다.

반응형