Java

[Java] JDBCTemplate이란? JDBCTemplate 사용법, RowMapper란?

펭귄코기 2023. 6. 13. 10:16

1. JDBCTemplate 이란?

 

JDBCTemplate은 JDBC 코어 패키지의 중앙 클래스로

JDBC 사용을 단순화하고 일반적인 오류를 방지하는데 도움을 준다

 

일반적으로 JDBC를 직접 사용하면 아래와 같은 작업을 반복한다

  • 커넥션 획득
  • statement를 준비하고 실행
  • 결과를 반복하도록 루프를 실행
  • 커넥션 종료, statement 및 resultset 종료
  • 트랜잭션을 다루기 위한 커넥션 동기화
  • 예외 발생 시 스프링 예외 변환기 실행

요약하면 JDBCTemplate은 개발자가 JDBC를

쉽게 사용할 수 있게 도와주는 클래스이다

 

2. JDBCTemplate 사용법

1) 설정

먼저 라이브러리를 프로젝트에 추가해 줘야한다

Gradle, Maven 에 따라 표기 방식이 다르다

 

Gradle 은 build.gradle 파일에 코드를 작성해주고

Maven 은 pom.xml 파일에 코드를 작성해 준다

 

Gradle

//JdbcTemplate 추가
implementation 'org.springframework.boot:spring-boot-starter-jdbc'

 

Maven

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

 

JDBCTemplate은 Spring-boot-starter-jdbc 에 포함되어 있다

 

2) DataSource 주입

JDBCTemplate은 DataSource를 필요로 한다

DataSource는 스프링 빈으로 등록해 사용한다

 

스프링 빈으로 직접 등록하고 주입 받는 방법

@Configuration
public class DataSourceConfiguration {

    @Bean
    public DataSource getDataSource() {

        DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();

        dataSourceBuilder.url("");
        dataSourceBuilder.username("");
        dataSourceBuilder.password("");
        dataSourceBuilder.driverClassName("");

        return dataSourceBuilder.build();
    }
}

 

 사용하고자 하는 곳에서 의존 관계 주입 받는 방법

private final JdbcTemplate jdbcTemplate;

public JdbcTemplateItemRepository(DataSource dataSource) {
    this.jdbcTemplate = new JdbcTemplate(dataSource);
}

 

보통 빈을 직접 만들기 보단 의존 관계를 주입받는 방법을 많이 쓴다

 

3. 쿼리 작성 및 실행

JDBCTemplate을 사용하는 방법은 공식문서에 나와있고

대표적인 몇가지만 알아보자

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html

 

JdbcTemplate (Spring Framework 6.0.9 API)

Execute a query for a result object, given static SQL. Uses a JDBC Statement, not a PreparedStatement. If you want to execute a static query with a PreparedStatement, use the overloaded JdbcOperations.queryForObject(String, Class, Object...) method with nu

docs.spring.io

 

1) queryForObject()

<T> T queryForObject(String sql, RowMapper<T> rowMapper, Object... args) throws DataAccessException;
  • sql : 실행할 sql문
  • rowMapper : 조회대상
  • args : 파라미터들

queryForObject() 를 사용하면 단건 조회를 할 수 있다

이때 조회 대상이 객체가 아닌 단순 데이터면

타입을 지정해서 사용하면 된다

 

int로 반환하기 위해

int rowCount = jdbcTemplate.queryForObject("select count(*) from t_actor",Integer.class);

 

preparedStatement  ? 를 이용해서 파라미터 바인딩도 할 수 있다

int countOfActorsNamedJoe = jdbcTemplate.queryForObject(
"select count(*) from t_actor where first_name = ?", Integer.class, "cho");

 

String을 조회할 수 도 있다

String lastName = jdbcTemplate.queryForObject(
"select last_name from t_actor where id = ?", String.class, 3000L);

 

그렇다면 객체를 조회하려면 어떻게 해야할까

RowMapper를 활용해서 조회할 수 있다

 

RowMapper는 반환 결과인 ResultSet을 객체로 변환해주는 클래스이다

 

순수 JDBC를 사용해서 객체를 조회하면 아래와 같이 작성해 줘야한다

// 쿼리 날리기
ResultSet rs = stat.excuteQuery("SELECT * FROM Item");

// 결과값 가져오기
while(rs.next()) {
     // item 객체에 값 저장
     item = new Item();
     item.setId(rs.getInt(1));
     item.setItemName(rs.getString(2));
     item.setPrice(rs.getInt(3));
     
     // 리스트에 추가
     itemList.add(item);
}

 

ResultSet의 결과를 개발자가 직접 꺼내 객체에 담아 저장한다

하지만 RowMapper를 이용하면 이러한 단순 반복 작업을 자동화 해준다

 

RowMapper의 mapRow() 메서드

T mapRow(ResultSet rs, int rowNum) throws SQLException;

 

ResultSet rs에 결과를 담아와 사용자가 원하는 객체에 담는다

rowNum은 반복되는 루프 중 현재 행의 번호를 나타낸다

public Item mapRow(ResultSet rs, int rowNum) throws SQLException {
    // ResultSet 값을 Item 객체에 저장
    Item item = new Item();
    item.setId(rs.getLong("id"));
    item.setItemName(rs.getString("item_name"));
    item.setPrice(rs.getInt("price"));
    
    // item 반환
    return item;
};

 

2) query()

query() 메서드를 사용하면 여러 건을 조회할 수 있다

 

public List<Actor> findAllActors() {
    return this.jdbcTemplate.query("select first_name, last_name from t_actor", actorRowMapper);
}

 

3) update()

INSERT, UPDATE, DELETE 등 데이터를 변경하고 싶을 때는

update() 메서드를 사용할 수 있다

SQL 실행 결과에 영향받은 로우 수를 int로 반환한다

 

등록 (INSERT)

jdbcTemplate.update("insert into t_actor (first_name, last_name) values (?, ?)","cho", "penguin");

 

수정 (UPDATE)

jdbcTemplate.update("update t_actor set last_name = ? where id = ?", "cho", 3000L);

 

삭제 (DELETE )

jdbcTemplate.update("delete from t_actor where id = ?", Long.valueOf(actorId));

 

4) execute()

임의의 SQL을 실행할 때는 execute() 메서드를 사용할 수 있다

테이블을 생성하는 DDL 등 사용할 수 있다

jdbcTemplate.execute("create table penguintable (id integer, name varchar(100))");