옛날에는 자바와 DB를 연결하기 위해서 JDBC를 사용해야만 했다. 나 또한 작년 학교 과제에서 PostgreSQL과 JDBC를 이용한 경험이 있다... 이번 스프링 강의를 들으며 JdbcTemplate이라는 아주 유용한 클래스를 알게 되었다. JdbcTemplate의 위력을 느끼기 위해 JDBC
를 간단히 맛보자.
public List<Member> findAll() {
String sql = "select * from member";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
List<Member> members = new ArrayList<>();
while(rs.next()) {
Member member = new Member();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
members.add(member);
}
return members;
} catch (Exception e) {
throw new IllegalStateException(e);
} finally {
close(conn, pstmt, rs);
}
}
위 코드는 JDBC를 이용한 전체 멤버 조회 코드이다. 삽입, id로 조회, name으로 조회 등 모든 기능을 위와 같이 하나하나 작성해야 한다. 불필요하게 반복되는 부분이 너무나도 많고 복잡하다.
이를 보완하기 위해 JdbcTemplate
이 탄생했다.
스프링에서 제공하는 클래스로 JDBC 코어 패키지의 중심 클래스이다. JdbcTemplate 외에도 NamedParameterJdbcTemplate, SimpleJdbcInsert, SimpleJdbcCall 등의 클래스들이 존재한다.
JdbcTemplate을 사용할 때는 아래와 같이 DataSource
를 항상 스프링 컨테이너에서 빈으로 구성해야 한다.
private final DataSource dataSource;
public SpringConfig(DataSource dataSource) {
this.dataSource = dataSource;
}
/* 멤버 수 조회 */
int result = jt.queryForObject("SELECT count(*) FROM members", Integer.class);
/* 해당 id("spring")를 가진 멤버의 이름 조회 */
String result = jt.queryForObject("SELECT name FROM members WHERE id = ?", "spring", String.class);
/* 해당 id(spring)를 가진 멤버 조회 */
Member result = jt.queryForObject("SELECT * FROM members WHERE id = ?", "spring", memberRowMapper());
private RowMapper<Member> memberRowMapper() {
return (rs, rowNum) -> {
Member member = new Member();
member.setId(rs.getString("id"));
member.setName(rs.getString("name"));
member.setPw(rs.getString("pw"));
return member;
};
}
객체를 조회할 때는 RowMapper
를 활용한다. 여기서는 memberRowMapper()
로 따로 정의해주었다. 이는 데이터베이스의 반환 결과인 ResultSet을 Member 객체로 변환해 준다. Interger, String은 컴파일러가 해당 타입에 맞게 알아서 매핑해주지만 Member는 우리가 생성한 객체이기 때문에 직접 Mapping Logic을 구현해야 한다.
List<Member> result = jt.query("SELECT * FROM members", memberRowMapper());
/* memberRowMapper()는 위와 같이 생성 */
실행 시 SQL 실행 결과에 영향받은 행의 수를 int로 반환한다.
/* 멤버 등록 */
jt.update("INSERT INTO members(id, pw, name) VALUES(?, ?)",
"spring", "1234", "Jenny");
/* 멤버 수정 */
jt.update("UPDATE members SET name = ? WHERE id = ?",
"Jenny", "winter");
/* 멤버 삭제 */
jt.update("DELETE FROM members WHERE id = ?",
"winter");
임의의 SQL을 실행할 때는 위 메서드를 사용할 수 있다.