#Spring. Spring JDBC 사용법

gisung2215·2021년 1월 1일
0
post-thumbnail

Spring JDBC 개요

JDBC를 이용해서 프로그래밍을 하게 되면 반복적인 코드가 많이 발생하며,
이런 반복적인 코드는 개발자의 생산성을 떨어트리는 주된 원인이 된다.
이러한 문제를 해결하기 위해 등장한 것이 Spring JDBC 입니다.

JDBC Template

  • org.springframework.jdbc.core에서 가장 중요한 클래스입니다.
  • 리소스 생성, 해지를 처리해서 연결을 닫는 것을 잊어 발생하는 문제 등을 피할 수 있도록 합니다.
  • 스테이먼트(Statement)의 생성과 실행을 처리합니다.
  • SQL 조회, 업데이트, 저장 프로시저 호출, ResultSet 반복호출 등을 실행합니다.
  • JDBC 예외가 발생할 경우 org.springframework.dao패키지에 정의되어 있는 일반적인 예외로 변환시킵니다.

NamedParameterJdbcTemplate

  • JdbcTemplate에서 JDBC statement 인자를 ?를 사용하는 대신 파라미터명을 사용하여 작성하는 것을 지원

SimpleJdbcTemplate (deprecated)

  • JdbcTemplateNamedParameterJdbcTemplate 합쳐 놓은 템플릿 클래스
  • 이제 JdbcTemplateNamedParameterJdbcTemplate에 모든 기능을 제공하기 때문에 삭제 예정될 예정

SimpleJdbcInsert

  • 테이블에 쉽게 데이터 insert 기능을 제공

NamedParameterJdbcTemplate 사용법

  • NamedParameterJdbcTemplate을 사용하면 SQL 쿼리 안에서 ?로 표현되던 파라미터를 :productName과 같이 이름을 붙여서 지정할 수 있습니다. 여러 개의 파라미터가 있는 쿼리를 실행할 때는 JdbcTemplate보다 NamedParameterJdbcTemplate을 사용하기를 권장합니다.

  • NamedParameterJdbcTemplateDataSource 객체를 필요로 하며, 아래와 같이 선언합니다.

private NamedParameterJdbcTemplate jdbc 
			= new NamedParameterJdbcTemplate(dataSource);

RowMapper

RowMapper는 JDBC의 인터페이스인 ResultSet에서 원하는 객체로 타입을 변환하는 역할을 합니다. 기본적인 전략을 구현한 클래스는 Spring JDBC에서 제공을 합니다.

BeanPropertyRowMapper

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입니다. 하지만 별다른 설정이 없어도 자동으로 매핑이 되었습니다.

CRUD 구현 소스

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

0개의 댓글