포스트

2021-05-17-TIL

2021-05-17-TIL

Spring Boot + Spring JDBC Template

  • https://pyxispub.uzuki.live/?p=1715
  • https://mkyong.com/spring-boot/spring-boot-jdbc-examples/
  • https://www.baeldung.com/spring-jdbc-jdbctemplate
  • https://gmlwjd9405.github.io/2018/12/19/jdbctemplate-usage.html
  • https://github.com/benelog/spring-jdbc-tips
  • https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-usagenotes-connect-drivermanager.html#connector-j-examples-connection-drivermanager
  • https://www.youtube.com/watch?v=wyoHgs6Sa20&t=20s

JdbcTemplate이 대신해 주는 일

순수 JDBC로 쿼리 하나를 실행하려면 DriverManager나 DataSource에서 커넥션을 얻고, PreparedStatement를 만들고, 값을 바인딩하고, ResultSet을 돌며 객체로 옮기고, 마지막에 세 자원을 모두 닫아야 한다. 링크한 MySQL Connector/J 문서의 예제가 바로 이 흐름이다.

JdbcTemplate은 이 중 반복되는 부분을 맡는다. Spring 문서에 따르면 자원의 생성과 해제를 처리해서 커넥션을 닫지 않는 실수를 막고, JDBC의 SQLException을 org.springframework.dao 패키지의 DataAccessException 계층으로 바꿔 준다. 애플리케이션 코드는 SQL과 결과를 객체로 옮기는 방법만 제공하면 된다.

1
2
3
4
5
6
7
8
9
10
11
// 단일 값
int count = jdbcTemplate.queryForObject("select count(*) from room", Integer.class);

// 한 행을 객체로
Room room = jdbcTemplate.queryForObject(
        "select id, location from room where id = ?",
        (rs, rowNum) -> new Room(rs.getLong("id"), rs.getString("location")),
        1L);

// 변경
jdbcTemplate.update("insert into room (location) values (?)", "서울");

알아 둘 점

  • queryForObject는 결과가 정확히 한 행이어야 한다. 0행이거나 여러 행이면 IncorrectResultSizeDataAccessException을 던지므로(JdbcTemplate Javadoc), 없을 수 있는 조회는 query로 리스트를 받아 비었는지 확인한다.
  • ? 자리표시자가 많아지면 순서를 헷갈리기 쉽다. NamedParameterJdbcTemplate을 쓰면 :location처럼 이름으로 바인딩할 수 있다.
  • 문서에 따르면 JdbcTemplate 인스턴스는 한 번 설정하면 스레드 안전하다. 그래서 DAO마다 새로 만들 필요 없이 빈 하나를 주입받아 공유한다. Spring Boot는 JdbcTemplate과 NamedParameterJdbcTemplate을 자동 구성하므로 생성자로 바로 주입받으면 된다(Spring Boot 문서).
참고한 자료외부 출처 2

외부 출처

이 글은 저작권자의 CC BY 4.0 라이선스를 따릅니다.

댓글

아직 댓글이 없습니다