Spring JDBC 실습5

oyeon·2021년 1월 18일
0
post-custom-banner

1건 SELECT, DELECT

  1. RoleDaoSqls.java 수정 - 쿼리 추가
package kr.or.connect.daoexam.dao;

public class RoleDaoSqls {
	public static final String SELECT_BY_ROLE_ID = "SELECT role_id, description FROM role WHERE role_id = :roleId";
	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 DELETE_BY_ROLE_ID = "DELETE FROM role WHERE role_id = :roleId";
}
  1. RoleDao.java 수정 - 메서드 추가
package kr.or.connect.daoexam.dao;

import static kr.or.connect.daoexam.dao.RoleDaoSqls.*;

import java.util.Collections;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.stereotype.Repository;

import kr.or.connect.daoexam.dto.Role;

@Repository
public class RoleDao {
	private NamedParameterJdbcTemplate jdbc;
	private SimpleJdbcInsert insertAction;
	
	private RowMapper<Role> rowMapper = BeanPropertyRowMapper.newInstance(Role.class);

	public RoleDao(DataSource dataSource) {
		this.jdbc = new NamedParameterJdbcTemplate(dataSource);
		this.insertAction = new SimpleJdbcInsert(dataSource).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);
	}
	
	/* SingletomMap : 값이 여러 개가 아니라 한 건만 넣어서 사용할 때 주로 사용
	 * 값이 roleId 1개 들어오기 때문에 굳이 객체를 만들 필요 없음
	 * */
	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_ROLE_ID, params, rowMapper);
		// select를 했는데 해당 조건에 맞는 값이 없을 때 결과 값이 
		// 제대로 넘어오지 않을 수 있으므로 적절한 Exception 필요
		} catch (EmptyResultDataAccessException e) {
			return null;
		}
	}
}
  1. JDBCTest.java 수정
package kr.or.connect.daoexam.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import kr.or.connect.daoexam.config.ApplicationConfig;
import kr.or.connect.daoexam.dao.RoleDao;
import kr.or.connect.daoexam.dto.Role;

public class JDBCTest {
	public static void main(String[] args) {
		ApplicationContext ac = new AnnotationConfigApplicationContext(ApplicationConfig.class);
		
		RoleDao roleDao = ac.getBean(RoleDao.class);
				
        	// 1건 SELECT
//		Role resultRole = roleDao.selectById(301);
//		System.out.println(resultRole);

		// 1건 DELETE
		int count = roleDao.deleteById(301);
		System.out.println(count);
	}
}

결과

  • 1건 SELECT
  • 1건 DELETE

생각해보기

JdbcTemplate을 이용하지 않고 NamedParameterJdbcTemplate를 이용하여 DAO를 작성한 이유가 무엇일까?

  • JdbcTemplate을 사용하면 자바에 존재하는 쿼리문과 DB 연산으로 부터 발생하는 값 객체의 파라미터를 관리하기 매우 힘들어진다.

  • 대표적인 예로, Java는 클래스의 인스턴스 변수에 camelCase를 주로 사용하고 sql은 Column명으로 snake case를 주로 사용하기 때문에 서로 통신하기 위해서 Parsing 하는 작업이 필요 하고 이러한 작업들을 NamedParameterJdbcTemplate이 지원해준다.

  • 만약 JdbcTemplate을 직접 사용한다면 NamedParameterJdbcTemplate가 재공해주는 Parsing 작업들을 개발자가 직접해줘야만 하고 이는 Type Safe하지 못할 뿐더러 많은 중복된 코드를 발생시킨다.

  • 이러한 중복된 코드는 모든 에러의 근원이며 이를 없애기 위해서 JdbcTemplate 대신 NamedParameterJdbcTemplate를 사용할 것을 권장한다.

profile
Enjoy to study
post-custom-banner

0개의 댓글