.class 이자식.. 여기저기서 짜깁기해서 이해하느라 힘들었다.. 아 근데 RowMapper랑 ResultSeltExtractor 비교가 더 오래걸림ㅠㅠㅋㅋ 자바에서 DML 처리하는 게 익숙해질 수 있도록 예제를 많이 주셔서 오전 시간 대부분을 문풀에 썼더니 시간이 빨리감. 처음 두 문제에서 계속 에러가 났는데 SQL Developer에서 INSERT에 대한 Commit을 안한 게 문제였음 휴 ^^.. 아니 왜 안돼!!!를 한 5천 번 하니까 발견함 ㅋㅋㅋ
?로 홀더 처리//문자열 유사 검색 INSTR()
JdbcTemplate template = JdbcUtil.getTemplate();
String sql = "SELECT * FROM POCKET_MONSTER "
+ "WHERE INSTR(NAME, ?) > 0";
Object[] param = {"이상해"};
RowMapper<PocketMonsterDto> mapper = (rs, idx) -> {
PocketMonsterDto dto = new PocketMonsterDto();
dto.setNo(rs.getInt("no"));
dto.setName(rs.getString("name"));
dto.setType(rs.getString("type"));
return dto;
};
List<PocketMonsterDto> list = template.query(sql, mapper, param);
//sql을 먼저 써야함. mapper, param은 순서 바뀌어도 됨
System.out.println("검색 결과 : " + list.size() + "개");
for(PocketMonsterDto dto : list) {
System.out.println(dto);
}
SELECT * FROM POCKET_MONSTER WHERE NAME LIKE '%?%’|| → ‘%’||?||’%’//문자열 유사 검색 LIKE
String sql = "SELECT QUERY: SELECT * FROM POCKET_MONSTER "
+ "WHERE NAME LIKE '%'||'?'||'%’";
Object[] param = {"이상해"};
queryForObject() 사용Integer.class)JdbcTemplate template = JdbcUtil.getTemplate();
String sql = "SELECT COUNT(*) FROM MUSIC";
//읽어올 데이터의 자료형을 인자로 넣어야 함
int count = template.queryForObject(sql, Integer.class);
System.out.println("count = " + count);
* https://roadofdevelopment.tistory.com/49
클래스의 구조 자체를 하나의 클래스로 표현해놓은 클래스
클래스명.class: 이 형태로 호출 시, 해당 클래스의 정보를 담은 Class 클래스가 반환됨* https://joont.tistory.com/165
* https://nam-ki-bok.github.io/java/Java_reflection/
PK를 조건으로 설정해 하나의 결과값을 추출하고 싶을 때 사용int musicNo = 1; //이 노래가 있을지 없을지는 모르지만, 있으면 결과가 1개 나옴
JdbcTemplate template = JdbcUtil.getTemplate();
String sql = "SELECT * FROM MUSIC WHERE MUSIC_NO = ?";
Object[] param = {musicNo};
ResultSetExtractor<MusicDto> extractor = new ResultSetExtractor<MusicDto>() {
//익명중첩클래스로 추출 방법을 알려줘야 함
//매개변수에 idx(rowNum) 불필요(데이터가 1개이므로)
@Override
public MusicDto extractData(ResultSet rs)
throws SQLException, DataAccessException {
//데이터가 있는 경우와 없는 경우를 구분해서 처리하는 방법을 알려줌
if(rs.next()) { //rs에 데이터가 있으면
MusicDto dto = new MusicDto();
dto.setMusicNo(rs.getInt("music_no"));
dto.setMusicArtist(rs.getString("music_artist"));
dto.setMusicAlbum(rs.getString("music_album"));
dto.setMusicPlay(rs.getInt("music_play"));
dto.setReleaseTime(rs.getString("release_time"));
return dto;
}else { //rs에 데이터가 없으면
return null;
}
}
};
//sql 구문 실행 시 얻을 것으로 기대되는 자료형은? MusicDto
//[자료형] List: 결과가 여러 개, DTO: 결과가 1개
MusicDto musicDto = template.query(sql, extractor, param);
if(musicDto == null) {
System.out.println("존재하지 않는 음원 번호");
}else {
System.out.println(musicDto);
}
용도에 맞는 도구를 사용할 것을 권장함(List는 결과가 0개 이상, 객체는 결과가 0 또는 1개)
결과값이 1개인 경우 List로 반환되는 것이 불필요
결과값이 null(검색 결과가 0건)인 경우에는 mapRow 메서드가 호출되기도 전에 스프링 프레임워크가 EmptyResultDataAccessException 예외를 발생시킴. (따라서 RowMapper를 사용할 때는 조회 결과가 반드시 1건 이상 존재한다고 가정하고 구현하면 됨.)
만약 null인 상황에 대해 직접 컨트롤하고 싶다면 상세 코드를 추가로 작성해야 함.
List<MusicDto> list = template.query(sql, mapper, param);
//MusicDto musicDto = list.get(0) or null;
MusicDto musicDto; //객체를 선언만 하고 조건문으로 처리
if(list.isEmpty()) {
musicDto = null;
}
else {
musicDto = list.get(0);
}
System.out.println(musicDto);
순차적으로 읽으면서 원하는 POJO 형태로 매핑할 때 사용자유롭게 제어하며 원하는 POJO형태로 매핑할 때 사용if(rs.next()) or while(rs.next()))* https://changrea.io/spring/spring-jdbc/