SQL문 전송 및 실행 후 실행 결과(ResultSet)를 전달받는 경우 : 조회(SELECT)
집계 함수에 대한 조회
- sum, avg, max, min, count
- 집계 함수의 결과는 ResultSet이지만 데이터는 하나밖에 없다 (단일 행 함수)
1) JdbcTemplate 클래스의 인스턴스 생성 - JdbcUtil 클래스에서 .getTemplate 메소드 호출
2) SQL문 작성
3) JdbcTemplate 클래스의 queryForObject() 메소드 - .queryForObject(sql문, 자료형.class)
<T> T | queryForObject(String sql, Class<T> requiredType) | SQL 실행 후 <T> 형태의 결과값을 반환 |
** .class 란?
- 클래스 생성시 자동으로 생기는 클래스 정보 객체
ex) MUSIC 테이블
- MUSIC 테이블에서 데이터의 갯수(COUNT)
import org.springframework.jdbc.core.JdbcTemplate;
import util.JdbcUtil;
public class Test07 {
public static void main(String[] args) {
// 1. JdbcTemplate 클래스의 인스턴스 생성 - .getTemplate() 메소드
JdbcTemplate template = JdbcUtil.getTemplate();
// 2. SQL문 작성 (갯수)
String sql = "select count(*) from music";
// 3. RowMapper 클래스는 필요없음
// 4. SQL문 전송 및 실행 후 int 형태의 값을 반환
int count = template.queryForObject(sql, int.class);
// 확인용 출력
System.out.println("count = " + count);
}
}
- MUSIC 테이블에서 모든 데이터의 재생수(MUSIC_PLAY)의 합계(SUM)
public class Test08 {
public static void main(String[] args) {
// 1. JdbcTemplate 클래스의 인스턴스 생성 - .getTemplate() 메소드
JdbcTemplate template = JdbcUtil.getTemplate();
// 2. SQL문 작성 (합계)
String sql = "select sum(music_play) from music";
// 3. RowMapper 클래스는 필요없음
// 4. SQL문 전송 및 실행 후 int 형태의 값을 반환
int sum = template.queryForObject(sql, int.class);
// 확인용 출력
System.out.println("sum = " + sum);
}
}
단일 조회 (특정 조건을 만족하는 하나의 데이터만 상세 조회)
- 집계 함수 조회는 ResultSet을 mapping할 컬럼이 1개(평균, 합계, 최대, 최소, 갯수)이지만
단일 조회의 ResultSet은 mapping할 컬럼이 조회할 테이블의 컬럼 수와 같다
- 따라서 기존의 조회처럼 RowMapper로 ResultSet의 각 행을 반환 인스턴스에 mapping해야 한다
1) JdbcTemplate 클래스의 인스턴스 생성 - JdbcUtil 클래스에서 .getTemplate 메소드 호출
2) SQL문 작성
3) SQL문의 물음표 ?(바인딩 변수)에 들어갈 Object 타입의 배열 param 생성
4) ResultSetExtractor 클래스의 인스턴스 extractor 생성 - extractData() 메소드 오버라이딩
- 만약 ResultSet이 존재하면(rs.next()) DTO 타입 인스턴스에 mapping 진행
- 그렇지 않다면 null값 반환
5) DTO 타입 인스턴스를 생성하여 JdbcTemplate 클래스의 query() 메소드 실행 결과를 저장
- .query(sql문, mapper, param)
6) 저장된 인스턴스의 정보 출력
ResultSetExtractor<T>
- JdbcTemplate에서 사용하는 인터페이스 (Spring Framework에서 제공)
- SQL문의 결과(ResultSet)의 각 행을 mapping하기 위해 extractData() 메소드를 구현(implement)해야 한다
- ResultSetExtractor의 메소드 (추상 메소드)
<T> | extractDate(ResultSet rs) | ResultSet을 <T>타입의 객체에 mapping하여 반환 |
** RowMapper<T>와 ResultSetExtractor<T>의 차이점
- RowMapper<T>는 <T> 타입 객체 여러개를 mapping하여 반환한다
- ResultSetExtractor<T>는 <T> 타입 객체 하나를 mapping하여 반환한다
ex) MUSIC 테이블에서 특정 번호(MUSIC_NO)의 노래 정보 출력
1. MusicDto 생성
- 필드
- 생성자
- getter & setter
public class MusicDto {
// 필드
private int musicNo;
private String musicTitle;
private String musicArtist;
private String musicAlbum;
private int musicPlay;
private String releaseTitle;
// 생성자
public MusicDto() {
super();
}
// getter & setter
public int getMusicNo() {
return musicNo;
}
public void setMusicNo(int musicNo) {
this.musicNo = musicNo;
}
public String getMusicTitle() {
return musicTitle;
}
public void setMusicTitle(String musicTitle) {
this.musicTitle = musicTitle;
}
public String getMusicArtist() {
return musicArtist;
}
public void setMusicArtist(String musicArtist) {
this.musicArtist = musicArtist;
}
public String getMusicAlbum() {
return musicAlbum;
}
public void setMusicAlbum(String musicAlbum) {
this.musicAlbum = musicAlbum;
}
public int getMusicPlay() {
return musicPlay;
}
public void setMusicPlay(int musicPlay) {
this.musicPlay = musicPlay;
}
public String getReleaseTitle() {
return releaseTitle;
}
public void setReleaseTitle(String releaseTitle) {
this.releaseTitle = releaseTitle;
}
// toString 오버라이딩
@Override
public String toString() {
return "MusicDto [musicNo=" + musicNo + ", musicTitle=" + musicTitle + ", musicArtist=" + musicArtist
+ ", musicAlbum=" + musicAlbum + ", musicPlay=" + musicPlay + ", releaseTitle=" + releaseTitle + "]";
}
}
2. 단일 조회의 결과를 반환하는 메인 메소드
1) JdbcTemplate 클래스의 인스턴스 생성 - JdbcUtil 클래스에서 .getTemplate 메소드 호출
2) SQL문 작성
3) SQL문의 물음표 ?(바인딩 변수)에 들어갈 Object 타입의 배열 param 생성
4) ResultSetExtractor 클래스의 인스턴스 extractor 생성 - extractData() 메소드 오버라이딩
- 만약 ResultSet이 존재하면(rs.next()) MusicDto 타입 인스턴스에 mapping 진행
- 그렇지 않다면 null값 반환
5) MusicDto 타입 인스턴스를 생성하여 JdbcTemplate 클래스의 query() 메소드 실행 결과를 저장
- .query(sql문, mapper, param)
6) 저장된 인스턴스의 정보 출력
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import dto.MusicDto;
import util.JdbcUtil;
public class Test09 {
public static void main(String[] args) {
// 1. JdbcTemplate 클래스의 인스턴스 생성 - .getTemplate() 메소드
JdbcTemplate template = JdbcUtil.getTemplate();
// 2. SQL문 작성
String sql = "select * from music where music_no = ?";
// 3. 변수 선언 및 변수 배열 생성
int musicNo = 9;
Object[] param = {musicNo};
// 4. ResultSetExtractor의 인스턴스 생성
// ResultSetExtractor<T> : <T> 타입의 객체에 mapping을 하는 메소드
// <T> : mapping을 할 객체 타입
// - 인터페이스는 원래 인스턴스 생성이 불가능하지만
// 익명 중첩 클래스로서 메소드 오버라이딩만 해주면 인스턴스 생성이 가능하다
// - extractData() 메소드를 오버라이딩하여 mapping 방식을 정의한다
ResultSetExtractor<MusicDto> extractor = new ResultSetExtractor<MusicDto>() {
@Override
public MusicDto extractData(ResultSet rs) throws SQLException, DataAccessException {
if(rs.next()) { // ResultSet rs에 데이터가 있다면
MusicDto musicDto = new MusicDto();
musicDto.setMusicNo(rs.getInt("music_no"));
musicDto.setMusicTitle(rs.getString("music_title"));
musicDto.setMusicArtist(rs.getString("music_artist"));
musicDto.setMusicAlbum(rs.getString("music_album"));
musicDto.setMusicPlay(rs.getInt("music_play"));
musicDto.setReleaseTitle(rs.getString("release_title"));
return musicDto;
}
else { // ResultSet rs에 데이터가 없다면
return null;
}
}
};
// 5. SQL문 전송 및 실행 후 그 결과인 CustomerDto 타입의 ResultSET을 List에 저장
MusicDto musicDto = template.query(sql, extractor, param);
// 확인용 출력
if(musicDto == null) {
System.out.println("존재하지 않는 음원 번호");
}
else {
System.out.println(musicDto);
}
}
}
jdbc04까지
'국비교육 > 국비교육' 카테고리의 다른 글
day26 - 0830 (0) | 2022.08.30 |
---|---|
day25 - 0829 (0) | 2022.08.30 |
day23 - 0825 (0) | 2022.08.27 |
day22 - 0824 (0) | 2022.08.24 |
day21 - 0823 (0) | 2022.08.23 |