Spring Jdbc Template 실습 정리

라코마코·2020년 4월 20일
1

부스트코스 이론

목록 보기
3/6

config : java Config 파일들이 묶여있는곳
dao : DataAccess와 sqls가 묶여있는 곳
dto : DataTransaction object가 묶여있는곳

환경 설정

필요한것

  1. Spring 환경임으로 Spring-context가 필요하다.
  2. DB에 접속 (MySql) 할 예정임으로, MysqlConnector를 다운받아야한다.
  3. DB 접속과 connection pool을 대신 관리해줄 dbcp (apache common dbcp2) 가 필요하다.
  4. DB 트랜잭션을 처리할 spring-tx (transaction) 이 필요하다.
  5. Spring Jdbc Template를 사용할 예정임으로 spring-jdbc가 필요하다.

5가지 dependency들을 maven repository에서 찾아서 다운로드한다.

환경설정 코드

ApplicationConfig.class
이 환경 설정 클래스는, Spring과 관련된 설정을 모아둔 클래스이며
스프링 환경 설정 클래스의 root 역할을 할 예정이다.

package kr.or.connect.daoexam.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@ComponentScan(basePackages= {"kr.or.connect.daoexam.dao"})
@Import({DBConfig.class}) //다른 환경설정을 묶는다.
public class ApplicationConfig {

}

DBConfig.java
DBConfig 클래스는 DB 접속과 설정에 관한 정보들을 모아두는 클래스이다.


import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

@Configuration
@EnableTransactionManagement
public class DBConfig implements TransactionManagementConfigurer{
  private String drivuerClassName = "com.mysql.jdbc.Driver";
  private String url = "jdbc:mysql://localhost:3306/connectdb?useSSL=false";
  private String username = "connectuser";
  private String userPassword = "connect123!@#";
  
  @Bean
  public DataSource dataSource() {
    BasicDataSource ds = new BasicDataSource();
    ds.setDriverClassName(drivuerClassName);
    ds.setUrl(url);
    ds.setUsername(username);
    ds.setPassword(userPassword);
    return ds;
  }
  
  // 트랜 잭션 매니저 지정
  @Override
  public PlatformTransactionManager annotationDrivenTransactionManager() {
    return transactionManager();
  }
  
  //플랫폼 트랜잭션 매니저 지정
  @Bean
  public PlatformTransactionManager transactionManager() {
    return new DataSourceTransactionManager(dataSource());
  }
}

DTO 객체의 설정은 생략하겠다.
RoleDaoSqls 객체도, 단순히 쿼리문을 모아놓은 곳 이기 때문에 생략하겠다.

@EnableTransactionManager : 이 어노테이션이 부착되면, 트랜잭션 매니저가 자동으로 활성화된다.
PlatformTransactionManager 구현체가 기본으로 적용된다.

dao Spring JDBC Template 사용

// DAO에는 저장소라는 의미로 Repository가 붙
@Repository
public class RoleDao {
  // binding시 문자열로 매핑하는 NamedParameterJdbcTemplate
  private NamedParameterJdbcTemplate jdbc;
  // 모든 Bean Property를 담아주는 RowMapper을 자동으로 생성해주는 BeanPropertyRowMapper 객체.
  private RowMapper<Role> rowMapper = BeanPropertyRowMapper.newInstance(Role.class);
  // insert를 위한 객체
  private SimpleJdbcInsert insertAction;

  // 스프링 4.0 이상부터는, 객체가 Bean 객체라면 Autowired 없이도 DI 주입이된다.
  public RoleDao(DataSource dataSource) {
    this.jdbc = new NamedParameterJdbcTemplate(dataSource);
    this.insertAction = new SimpleJdbcInsert(dataSource).withTableName("role");
  }

  public List<Role> selectAll() {
    // 바인딩할 값이 없기 때문에 emptyMap을 넣어줌.
    // NamedJdbcTemplate는 Map을 이용해서 값을 바인딩함
    return jdbc.query(RoleDaoSqls.SELECT_ALL, Collections.emptyMap(), rowMapper);
  }

  public int insert(Role role) {
    // BeanPropertySqlParameterSource 는 빈 객체를 Map객체로 변환하는 객체
    // SqlParameterSource는 Sql에 들어갈 parameter Map 객체를 처리하는 인터페이스
    SqlParameterSource params = new BeanPropertySqlParameterSource(role);

    return insertAction.execute(params);
  }

  public int update(Role role) {
    SqlParameterSource params = new BeanPropertySqlParameterSource(role);
    return jdbc.update(RoleDaoSqls.UPDATE, params);
  }

  public int deleteById(Integer id) {
    Map<String, Integer> params = Collections.singletonMap("roleId", id);
    return jdbc.update(RoleDaoSqls.DELETE_BY_ROLE_ID, params);
  }
  
  public Role selectById(Integer id) {
    try {
      Map<String,Integer> params = Collections.singletonMap("roleId", id);
      // 1건 select 시에는 query ForObject가 나음
      return jdbc.queryForObject(RoleDaoSqls.SELECT_BY_ROLE_ID, params, rowMapper);
    }catch(EmptyResultDataAccessException e) {
      return null;
    }
  }
}

NamedParameterJdbcTemplate : 기존 jdbc는 변수 매핑을 ? 을 통해서 했지만
NamedParameterJdbcTemplate 객체에서는 변수 매핑을 이름을 통해서 하는것이 가능하다. :variable 식으로 변수 앞에 : 를 두어 구분한다.

사용하기 위해서는 DB와 연결된 dataSource와 연결되어져 있어야한다.

NamedParamterJdbcTemplate는 기본적으로 변수를 Map 객체를 통해서 받아 적용시킨다.
NamedParameterJdbcTemplate.queryForObject(sql,params(Map),rowMapper) : 한줄의 열을 처리함

NamedParameterJdbcTemplate.query(sql,params,rowMapper) : 여러 줄을 처리하고 리턴
.update(sql,params,rowMapper) : delete,insert,update 등을 처리하는 메소드

BeanPropertyRowMapper : Bean Property를 기반으로 RowMapper를 생성한다.

RowMapper : jdbc의 rowMapper와 역할이 같다. 이름에서 알 수 있듯이 테이블 행마다 resultSet 객체를 통해 매핑하는것을 가능하게 하는 객체이다.

Custom RowMapper

class BaboMapper implements RowMapper<Role>{

  @Override
  public Role mapRow(ResultSet rs, int rowNum) throws SQLException {
    Role role = new Role();
    role.setDescription(rs.getString("description"));
    role.setRoleID(rs.getInt("roleID"));
    return role;
  } 
}

SimpleJdbcInsert : 객체가 들어오면 그것을 테이블에 넣는 아주 간단한 객체 매핑은 NamedParamter처럼 Map으로 들어와야한다.

사용하기 위해선 dataSource와, 데이터를 넣을 테이블의 이름이 정의되어져 있어야 한다.

SqlParameterSource : Sql에 들어가는 parater값 ( Map 객체 ) 를 처리 하는 인터페이스.

BeanPropertySqlParameterSource : 빈 객체를 Map 객체로 변환시켜주는 객체

Collections.singletonMap(key,value) : 싱글톤 Map을 생성하는 static 메소드

사용된 객체, 사용법 정리

RowMapper : 쿼리 행 처리하는 객체

class BaboMapper implements RowMapper<Role>{

  @Override
  public Role mapRow(ResultSet rs, int rowNum) throws SQLException {
    Role role = new Role();
    role.setDescription(rs.getString("description"));
    role.setRoleID(rs.getInt("roleID"));
    return role;
  } 
}

NamedParameterJdbcTemplate처럼 쿼리를 날리는 객체의 마지막 행에 인자로 들어감.
여러줄의 행일경우 리스트로 리턴함

NamedParameterJdbcTemplate

NamedParameterJdbcTemplate jdbc = new NamedParameterJdbcTemplate(dataSource)

Jdbc를 이름으로 매핑하여 쿼리를 날리는 객체

이제부터 NPJT로 줄여서 부르겠음

query 메소드

query(String sql , Map params,RowMapper rowmapper)

SELECT 같은 일반 쿼리를 날리는데 사용되는 NPJT의 메소드

queryForObject

query(String sql , Map params,RowMapper rowmapper or Object class)

SELECT 같은 일반 쿼리를 날리는 용도지만 한줄의 행만 처리할때 사용된다.

update

update(String sql,Map params,RowMapper rowmapper);

DELETE INSERT UPDATE 같은 DML 처리용 NPJT의 메소드

SimpleJdbcInsert

SimpleJdbcInsert insert = new SimpleJdbcInsert(dataSource)
.withTableName("babo")
.usingGeneratedKeyColumns("id");

Insert 문을 전용으로 처리 하기 위해 태어난 JdbcInsert 구문

객체 생성시 dataSource와 , 사용할 테이블을 지정해줘야 하며, insert시 자동으로 pk키를 생성하는 기능도 있다.

execute

insertAction.execute(Map params);

Map에 parameter를 담아서 execute 메소드를 실행시키면 insert가 이루어진다.

executeAndReturnKey

insertActionn.executeAndReturnKey(params).longValue();

쿼리를 실행후 생성된 key 값을 리턴하게 된다.

BeanPropertyRowMapper

Bean 객체를 기반으로 RowMapper를 생성하는 객체

newInstance

RowMapper<GuestBook> rowMapper = BeanPropertyMapper.newInstance(GuestBook.class);

GuestBook 빈을 기반으로 하여 RowMapper를 생성한다.

BeanPropertySqlParameterSource

SqlParameterSource

SqlParameterSource는 sql의 파라미터를 관리하는 인터페이스이다. NPJT나 SimpleJdbc 같은 객체에서 파라미터를 담아 쿼리를 날리는 용도로 사용된다.

BeanPropertySqlParameterSource 객체는 빈 객체를 기반으로 하여 SqlParameterSource를 생성하는 객체이다.

SqlParameterSource params = new BeanPropertySqlParameterSource(book);

0개의 댓글