[스프링 인 액션] 3장 JDBC : 데이터로 작업하기
- 📕 Book/스프링 인 액션
- 2021. 7. 5.
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 사용해서 데이터 저장하기
- 깃허브 코드 참고
- PreparedStatementCreator 복잡하니까 쉽게 생성해보자
@SessionAttributes
- 세션에 모델객체를 저장해두고 계속 보존 가능하다
- 사용이 끝나면 즉 db 저장이 완료되면 세션을 제거한다
sessionStatus.setComplete();
📌 요약
- 스프링의 JdbcTemplate은 JDBC 작업을 굉장히 쉽게 해준다
- 데이터데이스가 생성해주는 ID 값을 알아야 할 때는 PreparedStatementCreator 의 KeyHolder 사용한다
- 데이터 추가를 쉽게 실행할 때는 SimpleJdbcInsert 사용한다
참고
반응형