JdbcTemplate는 Spring Framework에서 제공하는 클래스로, JDBC API를 보다 간편하고 효율적으로 사용할 수 있도록 도와주는 유틸리티입니다.
JDBC를 사용하여 데이터베이스에 접근하고 쿼리를 실행하기 위한 핵심 클래스입니다. 복잡한 JDBC 코드의 반복을 줄여주고, 데이터베이스 작업을 단순화하여 개발자가 비즈니스 로직에 집중할 수 있도록 도와줍니다.
1. 간편한 데이터베이스 작업:
JdbcTemplate는 데이터베이스 연결, 쿼리 실행, 결과 처리, 예외 처리 등을 내부적으로 처리하여 개발자가 직접 JDBC 코드를 작성하지 않아도 되게 해줍니다.
2. SQL 쿼리 실행:
다양한 SQL 쿼리를 쉽게 실행할 수 있는 메서드를 제공합니다. 예를 들어, 쿼리, 업데이트, 배치 작업 등을 지원합니다.
3. RowMapper 지원:
쿼리 결과를 객체로 매핑하기 위해 RowMapper 인터페이스를 쉽게 사용할 수 있어, 결과를 DTO나 POJO 형태로 변환할 수 있습니다.
4. Named Parameters 지원:
JdbcTemplate의 하위 클래스인 NamedParameterJdbcTemplate를 통해 이름 기반의 파라미터를 사용하여 SQL 쿼리를 더 가독성 있게 작성할 수 있습니다.


위에서 설정한 DataBase정보를 생성자 주입 방법 사용
* 다양한 방법이 있지만 생성자 주입 방법을 많이 사용한다 *
int countOfActorsNamedJoe = jdbcTemplate.queryForObject(
"select count(*) from t_actor where first_name = ?", Integer.class, "Joe");
단일 데이터를 반환할 때 사용되는 메서드입니다.
사용되는 매개변수는 순서대로
로 구성되어 있고, 조회대상이 단순 자료형인 경우, 위 예시 코드처럼 Integer.class를 사용하거나 문자열인 경우에는 String.class를 사용할 수 있습니다.
파라미터는 sql문의 "?" 의 순서에 따라서 차례대로 작성하면 됩니다.
List<String> result =
jdbcTemplate.query("select first_name from t_actor where last_name = ?", String.class, "Kim");
여러 데이터를 반환할 때 사용되는 메서드이다.
이외에는 위 queryForObject와 같습니다.
INSERT, UPDATE, DELETE 등 데이터를 변경하고 싶을 때는 update() 메서드를 사용할 수 있습니다.
SQL 실행 결과에 영향받은 로우 수를 int로 반환합니다.
jdbcTemplate.update("insert t_actor set last_name = ? where id = ?", "Banjo", 5276L);
사용법은 나머지 둘도 동일합니다.
sql문의 insert만 update, delete 로 바꿔주면 됩니다.
기본적인 쿼리문 작성 방법을 알아봤습니다!
하지만 여기서 무조건 의문이 생겨야 하는데,
객체를 반환받으려면 어떻게 해야하는 지??? 입니다.
RowMapper에 대해서 알아봅시다~
RowMapper는 데이터베이스의 반환 결과인 ResultSet을 객체로 변환해주는 클래스입니다.
Q. 굳이 ResultSet을 객체로 변환해서 받아와야하나요??
A. 무조건 꼭(?) 할 필요는 없는데 아래 비교를 보시죵..
@Override
public Optional<Member> findById(Long id) {
String sql = "select * from member where id = ?";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setLong(1, id);
rs = pstmt.executeQuery();
if(rs.next()) {
Member member = new Member();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
return Optional.of(member);
} else {
return Optional.empty();
}
} catch (Exception e) {
throw new IllegalStateException(e);
} finally {
close(conn, pstmt, rs);
}
}
@Override
public Optional<Member> findById(Long id) {
List<Member> result = jdbcTemplate.query("select * from member where id = ?", memberRowMapper(), id);
return result.stream().findAny();
}
예.. 같은 동작을 합니다..
Jdbc 코드에서는 ResultSet의 정보를 하나하나 객체에 다시 입력해줘야합니다. 하지만
JdbcTemplate 코드에서는 memberRowMapper()만 툭 던져주고 끝났죠?
이렇게 개발자의 반복노동을 줄여주는 고마운 클래스입니다.
T mapRow(ResultSet rs, int rowNum) throws SQLException;
먼저 알아야 하는 것은 mapRow() 메서드의 동작입니다.
private RowMapper<Member> memberRowMapper() {
return (rs, rowNum) -> {
Member member = new Member();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
return member;
};
}
RowMapper의 mapRow 메서드를 활용해서 람다식으로 작성할 수 있습니다.
예상되는 반환 결과를 위 코드처럼 미리 설정해 주면 됩니다!
기존 JdbcTemplate보다 더 편리하게 사용할 수 있는 클래스입니다.
기존 JdbcTemplate은 "?"에 맞춰서 차례대로 파라미터들을 설정해줘야했습니다.(바로 위에 있는 내용인데 기억하셔야됩니다!!)
하지만, NamedParameterJdbcTemplate은 자동으로 설정합니다.
위에서 ResultSet의 결과를 자동으로 객체에 담아주기 위해서 RowMapper를 사용했듯이 파라미터를 자동으로 설정해주기 위해서 우리는 파라미터들을 객체에 미리 넣어줄 건데 이 때 쓰이는 인터페이스입니다. 인터페이스니까 구현을 해야겠죠?
이 인터페이스를 구현하는 방법 2가지를 알려드리겠습니다.
BeanPropertySqlParameterSource param = new BeanPropertySqlParameterSource(member);
member객체의 변수들을 자동으로 바인딩하여 파라미터로 사용할 수 있습니다.
MapSqlParameterSource param = new MapSqlParameterSource()
.addValue("name", member.getName())
.addValue("id", member.getId());
변수들을 하나씩 설정해주지만, 이 방법의 장점은 객체에 없는 변수도 sql문의 파라미터로 사용할 수 있다는 것!입니다.
@Override
public Optional<Member> findById(Long id) {
List<Member> result = namedJdbcTemplate.query("select * from member where id = :id", memberRowMapper(), param);
return result.stream().findAny();
}
위에서 설정한 param을 넣어주고 "?" 대신에 :id 로 표현하는 것을 볼 수 있습니다! 그러면 어떤 "?"에 무슨 값을 넣어줘야할 지 고민할 필요없이
필요한 파라미터이름을 ":" 뒤에 쓰기만 하면 끝입니다.
출처 : https://velog.io/@aal2525/%EC%8A%A4%ED%94%84%EB%A7%81-DB-1%ED%8E%B8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%91%EA%B7%BC-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-Spring-Jdbc-Template#jdbctemplate
https://code-lab1.tistory.com/277