[Spring] 4 - JDBC
by me
해당 게시글의 전체 소스코드는 이곳 Github를 참고해 주세요
목차
- 데이터 액세스 층에 대해 이해
- 스프링 JDBC를 이해
- JUnit 을 이용한 스프링 유닛 테스트를 이해
데이터 액세스 층
데이터 액세스 층의 역할
- 데이터 액세스 처리를 비즈니스 로직 층에서 분리 하는 것
DAO(Data Access Object)
- 데이터 액세스 처리에 특화된 오브젝트
- Sun microsystems (현재 Oracle)가 제창한 J2EE 패턴 중 하나인 DAP 패턴 용어
DAO(Data Access Object) 패턴
- DAO 패턴은 데이터 취득과 변경에 데이터 처리를 DAO 오브젝트로 분리하는 패턴
자바의 데이터 액세스 기술
데이터 소스(Data Source)
데이터 소스 구현
JDBC
JDBC 이용의 문제점
- 대량의 소스 코드 를 기술
- 다양한 에러 원인을 파악하기 위한 코딩 필요
- 데이터베이스 제품마다 에러 코드가 달라서 코드의 일관성 유지가 어려움
스프링 JDBC
- JDBC를 래핑한 API를 제공해 소스 코드를 단순화
- JDBC를 직접 사용할 때 발생하는 장황한 코드를 은닉
- 커넥션 연결 종료
- SQL 문의 실행
- SQL 문 실행 결과 행에 대한 반복 처리
- 예외 처리
- 스프링 JDBC기 제공하는 중요 탬플릿
- JdbcTemplate
- NamedParameterTemplate
JdbcTemplate 클래스 제공 메서드
JdbcTemplate 클래스의 오브젝트 생성과 인젝션
스프링 JDBC - SELECT
취득 결과가 레코드 건수 또는 특정 컬럼만 취득할 경우
- queryForObject 메서드 사용 예제 1
- 제1인수 : SQL 문자열
- 제2인수 : 반환형 클래스 오브젝트 (int)
JdbcTemplate jdbcTemplate = ctx.getBean(JdbcTemplate.class);
int count = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM STUDENT", Integer.class);
- queryForObject 메서드 사용 예제 2
- 제1인수 : SQL 문자열, 제2인수 : 반환형 클래스 오브젝트(String)
- 제3인수 : 파라미터 값
String name = jdbcTemplate.queryForObject("SELECT username FROM STUDENT WHERE id= ?", String.class, id);
취득 결과가 한 레코드 값을 취득할 경우
- queryForMap 메서드
- 한 레코드 값을 Map(컬럼 이름을 키로 값을 저장) 데이터로 저장
Map<String, Object> student = jdbcTemplate.queryForMap("SELECT * FROM STUDENT WHERE id= ?", id);
String name = (String)student.get("username");
- queryForList 메서드
- 여러 레코드 값을 Map 데이터로 저장
List<Map<String, Object>> studentList = jdbcTemplate.queryForMap("SELECT * FROM STUDENT ");
도메인으로 변환할 경우
- queryForObject 메서드 와 query 메서드 를 이용한다
- queryForObject 메서드: 한 레코드를 가져올 때
- 제1인수 : SELECT 문
- 제2인수 : 도메인 자동 변환을 위한 스프링 제공 클래스 BeanPropertyRowMapper
- 제3인수 : SELECT 문의 파라미터
- BeanPropertyRowMapper를 사용할 경우 StudentVO의 프로퍼티 명과 테이블 컬럼 명이 같아야 함. 그렇지 않을 경우는 RowMapper 인터페이스를 구현해서 StudentVO로 변환 처리
public StudentVO read(String id) throws Exception {
StudentVO vo = null;
try {
vo = jdbcTemplate.queryForObject("SELECT * FROM STUDENT WHERE ID=?", new BeanPropertyRowMapper<StudentVO>(StudentVO.class), id);
}
catch(EmptyResultDataAccessException e) {
return vo;
}
return vo;
}
- query 메서드 : 여러 레코드를 가져올 때
- RowMapper 인터페이스를 구현한 익명 클래스를 정의
- 클래스내 mapRow() 추상 메서드를 정의
public List<StudentVO> readList() throws Exception {
List<StudentVO> studentlist = jdbcTemplate.query("SELECT * FROM STUDENT",
new RowMapper<StudentVO>() {
public StudentVO mapRow(ResultSet rs, int rowNum) throws SQLException {
StudentVO vo = new StudentVO();
vo.setId(rs.getString("ID"));
vo.setPasswd(rs.getString("PASSWD"));
vo.setUsername(rs.getString("USERNAME"));
vo.setSnum(rs.getString("SNUM"));
vo.setDepart(rs.getString("DEPART"));
vo.setMobile(rs.getString("MOBILE"));
vo.setEmail(rs.getString("EMAIL"));
return vo;
}
}
);
return studentlist;
}
스프링 JDBC - INSERT, UPDATE, DELETE
- update 메서드 만을 사용
INSERT
StudentVO vo;
jdbcTemplate.update("INSERT INTO STUDENT (ID, PASSWD, USERNAME, SNUM, DEPART, MOBILE, EMAIL)VALUES (?, ?, ?, ?, ?, ?, ?) " , vo.getId(), vo.getPasswd(), vo.getUsername(), vo.getSnum(), vo.getDepart(), vo.getMobile(), vo.getEmail());
DELETE
StudentVO vo;
jdbcTemplate.update( "DELETE FROM STUDENT WHERE ID=? ", vo.getId() );
JUnit을 이용한 스프링 유닛 테스트
스프링 테스트(Spring Test)
- 스프링 프레임워크에서 만든 클래스(@Controller, @Service, @Repository,@Component 등이 붙은 클래스)를 테스트하는 모듈
- 단위 테스트, 통합 테스트를 지원하기 위한 매커니즘이나 편리한 기능을 제공
- Junit 테스트 프레임워크를 사용하여 스프링 DI 컨테이너를 동작시키는 기능
- 트랜잭션 테스트를 상황에 맞게 제어하는 기능
- 애플리케이션 서버를 사용하지 않고 스프링 MVC 동작을 재현하는 기능
- RestTemplate을 이용해 HTTP 요청에 대한 임의 응답을 보내는 기능
스프링 테스트와 JUnit 테스팅 프레임워크 설정
- Pom.xml
<org.spring-framework.version>5.1.3.RELEASE</spring-framework.version>
<junit.version>4.12</junit.version>
...(중략)...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.spring-framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
- JUnit Test
package org.doorisopen.myspring.JUnitTest;
import org.doorisopen.myspring.Member.Domain.MemberVO;
import org.doorisopen.myspring.Member.Service.MemberService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/Testcontext.xml")
public class JUnitMember {
@Autowired
MemberService memberService;
@Test
public void testReadMember( ) throws Exception {
MemberVO member = memberService.readMember("Anonymous");
System.out.println(member);
}
}
만약!! 아래의 클래스를 import할 수 없는 문제가 발생한다면
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;프로젝트 오른쪽 클릭 -> Maven -> Project Update 를 해주면 된다.
References
- 대학교 웹 프레임워크 수업 정리한 내용 입니다.