Spring JDBC

배세훈·2021년 9월 12일
0

DB

목록 보기
11/19

Data Access Layer 이해하기

Spring JDBC 사용 과정

1. DataSource 설정

1.1 XML을 통한 DataSource 설정

  1. DB와의 연결을 위한 DB Server에 관한 정보(Property)를 설정한다.

    • url, driver, username, password
  2. 해당 proeprty file에 있는 값을 place holder을 통해 DataSource의 속성으로 설정한 후 해당 BasicDataSource를 bean으로 등록한다.

    • Spring JDBC를 사용하려면 먼저, DB Connection을 가져오는 DataSource를 SPring IoC 컨테이너의 공유 가능한 Bean으로 등록해야 한다.
  3. 생성된 BasicDataSource Bean을 Spring JDBC에 주입한다.

1.2 Java를 이용한 DataSource 등록

@Configuration
public class SpringJdbcConfig{
	
    @Bean
    public DataSource dataSource(){
    	DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUsername("test");
        dataSource.setPassword("password");
        
        return dataSource;
    }
}

2. DAO에서의 처리 과정

  1. DataSource 설정(위의 과정)

  2. 위에서 bean으로 등록한 DataSource를 setter parameter를 통해 주입한다.

    • @Autowired에 의해 DataSource Type에 해당하는 bean을 찾아서 주입한다.
    • 여기서는 DataSource interface 중 하나인 BasicDataSource를 찾아서 주입한다. (위의 과정에서 등록한 bean)
  3. Spring JDBC 접근 방법 중 하나인 JdbcTemplate 객체를 생성하여 dataSource를 주입한다.

  4. CRUD API를 제공한다

    • SQL문을 작성한다
    • RowMapper interface 구현을 통해 SQL의 결과(record type)를 객체(object type)에 매핑하여 결과를 리턴한다.
    • 개발자는 mapRow()라는 interface method를 정의하여 결과를 처리한다.
    • 한번만 사용하는 기능의 경우 RowMapper를 익명 클래스로 작성하여 사용한다.

위 코드에서 @Component("offersDao") or @Repository를 적는 이유

해당 DAO를 bean으로 등록함으로써 이전에 bean으로 등록한 dataSource를 가져와서 주입시키는 기능을 제공
해당 annotation이 없다면 xml이나 config를 통해 직접 bean을 등록하고 setter에 주입해야 한다.

3. JDBC Template 사용방법

1. queryForObject

  • Querying for an Integer
// 모든 학생의 수
String sql = "select count(*) from STUDENT";
int rowCnt = jdbcTemplateObject.queryForObject(sql, Integer.class);
  • Querying for an String
// 해당 학번(10)에 해당하는 학생의 이름
String sql = "select name from STUDENT where id = ?";
String name = jdbcTemplateObject.queryForObject(sql, new Object[]{10}, String.class);

// 위와 동일(hard coding)
String name1 = jdbcTemplateObject.queryForObject(sql, 10, String.class);
  • Querying and returning an object(하나의 객체)
// 해다아 학번(10)에 해당하는 학생 객체
String sql = "select * from student where id = ?";
Student student = jdbcTemplateObject.queryForObject(sql, new Object[]{10}, new StudentMapper());

public class StudentMapper implements RowMapper<Student> {
	
    @Override
    public Student mapRow(ResultSet rs, int rowNum) throws SQLException{
    	Student student = new Student();
        
        student.setID(rs.getInt("id"));
        student.setName(rs.getString("name"));
        student.setAge(rs.getInt("age"));
        
        return student;
    }
}

Integer, String은 컴파일러가 해당 타입에 맞게 알아서 매핑해주지만 우리가 만든 객체는 알 수 없기 때문에 직접 Mapping Logic을 구현해야 한다.

  • Querying and returning multiple objects(여러 개 객체)
// 모든 학생 객체
String sql = "select * from student";
List<Student> students = jdbcTemplateObject.query(sql, new StudentMapper());

// RowMapper interface의 구현 클래스 정의
public class StudentMapper implements RowMapper<Student> {
	
    @Override
    public Student mapRow(esultSet rs, int rowNum) thorws SQLException{
    	Student student = new Student();
        
        student.setId(rs.getInt("id"));
        student.setName(rs.getString("name"));
        student.setAge(rs.getInt("age"));
        
        return student;
    }
}

update

  • Inserting a row into the table
// 이름이 Zara, 학번이 11인 학생을 insert
String sql = "insert into student (name, age) values (?,?)";
jdbcTemplateObject.update(sql, new Object[]{"Zara", 11});
  • Updating a row into the table
// 학번이 10인 학생의 이름은 Zara로 수정
String sql = "update student set name = ? where id = ?";
jdbcTemplateObject.update(sql, new Object[]{"Zara", 10});
  • Deleting a row into the table
// 학번이 20인 학생을 삭제
String sql = "delete from student where id = ?";
jdbcTemplateObject.update(sql, new Object[]{20});

batch

public int[] batchUpdateUsingJdbcTemplate(List<Employee> employees){
	
    return jdbcTemplate.batchUpdate("insert into employee values (?,?,?,?)", 
    		new BatchPreparedStatementSetter(){
            	@Override
                public void setValues(PreparedStatement ps, int i) throws SQLException{
                  ps.setInt(1, employees.get(i).getId());
                  ps.setString(2, employees.get(i).getFirstName());
                  ps.setString(3, employees.get(i).getLastName());
                  ps.setString(4, employees.get(i).getAddress();
                }
                
                @Override
                public int getBatchSize(){
                	return 50;
                }
            }
    
}
profile
성장형 인간

0개의 댓글