JDBC를 이용해서 프로그래밍을 하게 되면 반복적인 코드가 많이 발생하며,
이런 반복적인 코드는 개발자의 생산성을 떨어트리는 주된 원인이 된다.
이러한 문제를 해결하기 위해 등장한 것이 Spring JDBC
입니다.
org.springframework.jdbc.core
에서 가장 중요한 클래스입니다.JdbcTemplate
에서 JDBC statement
인자를 ?를 사용하는 대신 파라미터명을 사용하여 작성하는 것을 지원JdbcTemplate
과 NamedParameterJdbcTemplate
합쳐 놓은 템플릿 클래스JdbcTemplate
과 NamedParameterJdbcTemplate
에 모든 기능을 제공하기 때문에 삭제 예정될 예정NamedParameterJdbcTemplate
을 사용하면 SQL 쿼리 안에서 ?로 표현되던 파라미터를 :productName
과 같이 이름을 붙여서 지정할 수 있습니다. 여러 개의 파라미터가 있는 쿼리를 실행할 때는 JdbcTemplate
보다 NamedParameterJdbcTemplate
을 사용하기를 권장합니다.
NamedParameterJdbcTemplate
은 DataSource
객체를 필요로 하며, 아래와 같이 선언합니다.
private NamedParameterJdbcTemplate jdbc
= new NamedParameterJdbcTemplate(dataSource);
RowMapper
는 JDBC의 인터페이스인 ResultSet
에서 원하는 객체로 타입을 변환하는 역할을 합니다. 기본적인 전략을 구현한 클래스는 Spring JDBC
에서 제공을 합니다.
DB의 컬럼명과 bean 객체의 속성명이 일치하다면 BeanPropertyRowMapper
를 이용하여 자동으로 객체변환을 할 수 있습니다. DB 컬럼명이 'snake_case'로 되어 있어도 'camelCase'로 선언된 클래스의 필드로 매핑이 됩니다.
다음과 같은 Role 객체가 있을때,
public class Role {
private int roleId;
private String description;
}
다음과 같은 코드로 ResultSet에서 Role로 타입을 변환하여 쿼리 결과를 받아옵니다.
public static final String SELECT_ALL
= "select role_id, description "
+ "from role order by role_id";
private RowMapper<Role> rowMapper
= BeanPropertyRowMapper.newInstance(Role.class);
public List<Role> selectAll(){
return jdbc.query(SELECT_ALL, Collections.emptyMap(), rowMapper);
}
DB컬럼의 이름인 trole_id는 snake_case였는데, Role객체의 속성이름인 roleId는 camelCase입니다. 하지만 별다른 설정이 없어도 자동으로 매핑이 되었습니다.
public class RoleDao {
public static final String SELECT_ALL
= "select role_id, description "
+ "from role order by role_id";
public static final String UPDATE
= "update role set description = :description "
+ " where role_id = :roleId";
public static final String SELECT_BY_ROKE_ID
= "select role_id, description from role "
+ "where role_id = :roleId";
public static final String DELETE_BY_ROLE_ID
= "delete from role where role_id = :roleId";
private NamedParameterJdbcTemplate jdbc;
private SimpleJdbcInsert insertAction;
private RowMapper<Role> rowMapper = BeanPropertyRowMapper.newInstance(Role.class);
public RoleDao(DataSource ds) {
this.jdbc = new NamedParameterJdbcTemplate(ds);
this.insertAction = new SimpleJdbcInsert(ds)
// insert 할 테이블 이름 설정
.withTableName("role");
}
public List<Role> selectAll(){
return jdbc.query(SELECT_ALL, Collections.emptyMap(), rowMapper);
}
public int insert(Role role) {
SqlParameterSource params = new BeanPropertySqlParameterSource(role);
return insertAction.execute(params);
}
public int update(Role role) {
SqlParameterSource params = new BeanPropertySqlParameterSource(role);
return jdbc.update(UPDATE, params);
}
public int deleteById(Integer id) {
Map<String, ?>params = Collections.singletonMap("roleId", id);
return jdbc.update(DELETE_BY_ROLE_ID, params);
}
public Role selectById(Integer id) {
try {
Map<String, ?> params = Collections.singletonMap("roleId", id);
return jdbc.queryForObject(SELECT_BY_ROKE_ID, params, rowMapper);
} catch (Exception e) {
return null;
}
}
}
https://www.boostcourse.org/web326/lecture/58973
https://github.com/benelog/spring-jdbc-tips/blob/master/spring-jdbc-core.md
https://velog.io/@dnstlr2933/%EC%8A%A4%ED%94%84%EB%A7%81-JdbcTemplate