💋 NamedParameterJdbcTemplate이란?
스프링 프레임워크에서 JDBC 작업을 보다 편리하게 할 수 있는 클래스이다.
어떻게 편리하게...?
- NamedParameterJdbcTemplate 클래스는 미완성의 JDBC Statement에 이제까지 쓰던 `?`(place holder) 대신에, 이름을 지어준 파라미터로 대체할 수 있게 된다.
- JdbcTemplate 클래스를 래핑하며, JdbcTemplate 클래스의 대부분의 기능을 사용할 수 있다.
사용 방법 위주로 공부해보자!
💋 언제 사용하면 좋을까?
Named Parameter를 사용하면 파라미터의 순서를 기억할 필요 없이, 파라미터에 이름을 지어서 쿼리를 실행할 수 있다.
파라미터 이름을 사용해 SQL 쿼리를 작성하고 실행하고 싶을 때 사용하면 된다!
💋 NamedParameterJdbcTemplate의 사용
NamedParameterJdbcTemplate에서 좋은건 SqlParameterSource 인터페이스를 제공한다는 것이다.
SqlParameterSource는 NamedParameterJdbcTemplate에서 사용하는 파라미터 값들의 소스이다.
SqlParameterSource의 구현체별로 이번 포스팅을 해보겠다!
✔ MapSqlParameterSource
/**
* MapSqlParameterSource public <T> T queryForObject(String sql, SqlParameterSource paramSource, Class<T>
* requiredType)
*/
public int useMapSqlParameterSource(String firstName) {
String sql = "select count(*) from customers where first_name = :first_name";
final MapSqlParameterSource namedParameters = new MapSqlParameterSource("first_name", firstName);
return namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
}
SqlParameterSource 인터페이스를 구현한 이 구현체는 java.util.Map를 생각하면 편하다.
MapSqlParameterSource는 생성자 아니면 addValue라는 메서드를 통해서 파라미터 이름과 값을 짝지어서 지정할 수 있다.
addValue를 사용하면 이렇게 만들 수 있다. 체이닝으로 계속 연결할 수 있다.
public int useMapSqlParameterSource(String firstName) {
String sql = "select count(*) from customers where first_name = :first_name";
final MapSqlParameterSource namedParameters = new MapSqlParameterSource()
.addValue("first_name", firstName);
return namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
}
만약 입력할 내용이 딱 한개라면 singletonMap을 활용해도 된다.
// some JDBC-backed DAO class...
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
public int countOfActorsByFirstName(String firstName) {
String sql = "select count(*) from customers where first_name = :first_name";
Map<String, String> namedParameters = Collections.singletonMap("first_name", firstName);
return this.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);
}
✔ BeanPropertySqlParameterSource
이 클래스 역시 NamedParameterJdbcTemplate에서 사용하는 파라미터 지정 방식 중 하나이다.
자바 빈 객체의 프로퍼티 이름과 값을 매핑하여 파라미터 맵을 생성한다.
* 자바 빈 객체는 자바 언어에서 사용되는 객체 중 하나로, 데이터를 저장하고 전달하는 데 사용된다.
일반적으로 DB에서 가져온 데이터를 저장하기 위해 사용되며, 내부에 캡슐화된 데이터에 접근을 하도록 getter 메서드를 구현한다.
* 자바 빈 객체는 일반적으로 직렬화가 가능한 객체이고, 보통 DTO 패턴으로 구현하며 getter와 setter 메서드를 가진다.
자바 빈 객체의 예시로는 아래와 같은 객체가 있다.
public class Customer {
private long id;
private String firstName, lastName;
public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public Customer(long id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public long getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}
BeanPropertySqlParameterSource 클래스는 생성자에 자바빈 객체를 파라미터로 전달해서 사용한다.
/**
* BeanPropertySqlParameterSource public <T> T queryForObject(String sql, SqlParameterSource paramSource, Class<T>
* requiredType)
*/
public int useBeanPropertySqlParameterSource(Customer customer) {
String sql = "select count(*) from customers where first_name = :firstName";
final BeanPropertySqlParameterSource namedParameterSource = new BeanPropertySqlParameterSource(customer);
return namedParameterJdbcTemplate.queryForObject(sql, namedParameterSource, Integer.class);
}
NamedParameterJdbcTemplate에서 SQL 쿼리를 실행할 때, 파라미터 이름과 값을 매핑하여 쿼리를 실행한다.
BeanPropertySqlParameterSource를 사용하면 JavaBean의 프로퍼티 이름과 값을 매핑하므로, 프로퍼티의 이름을 잘못 지정하거나, 값의 타입이 맞지 않는 경우 오류가 발생할 수 있다.
💋 참고자료