[스프링 인 액션] 3장 JDBC : 데이터로 작업하기

3장 데이터로 작업하기 - JDBC

💻 실습 : https://github.com/cusbert/spring-in-action-5th

🎯 이 장에서 배우는 내용

  • 스프링 JdbcTemplate 사용하기
  • SimpleJdbcInsert 사용해서 데이터 추가하기

3.1 JDBC를 사용해서 데이터 읽고 쓰기

  • 관계형 데이터를 사용할 때 선택지는 JDBC, JPA 두 개다
  • 스프링의 JDBC 지원은 JdbcTemplate 템플릿에 기반을 둔다
  • JdbcTemplate 를 사용해서 데이터베이스 쿼리하기
  • 명령문이나 데이터베이스 연결 객체를 생성하는 코드가 없다.
    메서드의 실행이 끝난 후 그런 객체들을 클린업하는 코드 또한 없다.
    catch 블록에서 올바르게 처리할 수 없는 예외를 처리하는 코드도 없다.
@Override
public Ingredient findById(String id) {
    return jdbcTemplate.queryForObject(
            "select id, name, type from Ingredient where id=?",
            this::mapRowToIngredient, id);
}

private Ingredient mapRowToIngredient(ResultSet rs, int rowNum) 
            throws SQLException {
    return new Ingredient(
            rs.getString("id"),
            rs.getString("name"),
            Ingredient.Type.valueOf(rs.getString("Type")));
}

3.1.2 JdbcTemplate 사용하기

JDBC 환경 구성

  • pom.xml 에 JDBC 스타터 의존성 추가
    <!-- jdbc -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
  • pom.xml 에 데이터베이스 의존성 추가 : mariadb
    <!-- mariadb -->
    <dependency>
        <groupId>org.mariadb.jdbc</groupId>
        <artifactId>mariadb-java-client</artifactId>
    </dependency>

JDBC Repository 정의하기

  • @Repository 지정하면 Spring component 검색에서 이 클래스를 자동으로 컨텍스트의 빈으로 생성한다
  • JdbcIngredientRepository 빈이 생성되면 @Autowired를 통해 스프링이 해당 빈을 JdbcTemplate 에 주입한다
  • JdbcIngredientRepository의 생성자에서는 jdbcTemplate 참조를 인스턴수 변수에 저장한다
  • 이 변수는 데이터베이스의 데이터를 쿼리하고 추가하기 위해 다른 메서드에서 사용된다
  • findAll() : jdbcTemplate.query(sql, RowMapper 인터페이스) 사용
  • findById(String id) : jdbcTemplate.queryForObject(sql, RowMapper 인터페이스)
  • save(Object object): jdbcTemplate.update(sql, 쿼리 매게변수에 저장할 값만 인자로 전달)
  • Ingredient repository가 해야 할 일을 IngredientRepository 인터페이스에 정의
public interface IngredientRepository {
    Iterable<Ingredient> findAll();
    Ingredient findById(String id);
    Ingredient save(Ingredient ingredient);
}
  • JdbcTemplate 사용하여 IngredientRepository 구현
@Repository
public class JdbcIngredientRepository implements IngredientRepository {

    private JdbcTemplate jdbcTemplate;

    @Autowired
    public JdbcIngredientRepository(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public Iterable<Ingredient> findAll() {
        return jdbcTemplate.query(
                "select id, name, type from Ingredient",
                this::mapRowToIngredient);

    }

    @Override
    public Ingredient findById(String id) {
        return jdbcTemplate.queryForObject(
                "select id, name, type from Ingredient where id=?",
                this::mapRowToIngredient, id);
    }

    @Override
    public Ingredient save(Ingredient ingredient) {
        jdbcTemplate.update(
                "insert into Ingredient (id, name, type) values (?, ?, ?)",
                ingredient.getId(),
                ingredient.getName(),
                ingredient.getType().toString());
        return ingredient;
    }
}

3.1.3 스키마 정의하고 데이터 추가하기

3.1.4 타코와 주문 데이터 추가하기

  • JdbcTemplate 으로 데이터 저장하는 방법

JdbcTemplate 사용해서 데이터 저장하기

  • 깃허브 코드 참고
  • update()메소드는 PreparedStatementCreator 객체와 KeyHolder 객체를 인자로 받는다.
  • keyHolder.getKey().longValue()는 타코 ID 를 반환한다

SimpleJdbcInsert 사용해서 데이터 저장하기

@SessionAttributes

  • 세션에 모델객체를 저장해두고 계속 보존 가능하다
  • 사용이 끝나면 즉 db 저장이 완료되면 세션을 제거한다
sessionStatus.setComplete();

📌 요약

  • 스프링의 JdbcTemplate은 JDBC 작업을 굉장히 쉽게 해준다
  • 데이터데이스가 생성해주는 ID 값을 알아야 할 때는 PreparedStatementCreator 의 KeyHolder 사용한다
  • 데이터 추가를 쉽게 실행할 때는 SimpleJdbcInsert 사용한다

참고

반응형

댓글

Designed by JB FACTORY