1) DB가 바뀌면 update, 읽어오면 query 계열
먼저 잡은 기준은 다음 두 줄이다.
- DB에 변화 (INSERT / UPDATE / DELETE)가 생기는 작업은 JdbcTemplate.update()를 사용한다.
- DB를 읽어오는 SELECT는 반환이 필요하므로 queryForObject() 또는 query()를 사용한다. 특히 단건 (select one)은 queryForObject()를 사용한다.
여기서 주의할 점은 “select는 다 queryForObject”가 아니라 단건은 queryForObject, 리스트는 query로 나뉜다는 점이다.
2) 반환 (매핑)을 직접 지정해야 해서 SELECT가 더 까다f롭다
SELECT 파트로 넘어가면서 강조한 포인트는 ‘반환이 있다’는 점이다.
- CUD는 결과를 int (영향받은 행 수)로 받아서 성공 / 실패 판단만 하면 되지만
- SELECT는 DB에서 가져온 결과를 DTO로 만들어서 반환해야 한다.
그래서 “어떻게 반환할지” 정보가 필요하고 그 역할을 하는 클래스가 필요하다고 설명한다.
3) queryForObject() 인자 구성: “반환 정보 (매핑) + 파라미터”
queryForObject()는 update()와 인자 구성이 다르다고 정리한다.
- update()는 보통 SQL + 파라미터
- queryForObject()는 어떻게 반환할지(매핑) + 파라미터가 추가로 필요
“SELECT류는 반환이 있으니까 어떻게 반환할지를 먼저 쓰고 그 다음 파라미터를 넣는다”라고 설명한다.
그리고 마지막 정리에서 더 명확하게 문장으로 고정한다.
- 첫 번째 인자 = SQL
- 중간 인자 = 어떻게 반환할지
- 마지막 인자 = 파라미터 전달
4) 컬럼 → DTO 필드 매핑을 직접 지정해야 한다
- “어떤 컬럼이 어떤 멤버 변수인지 짚어줘야 된다.”
DB에서 가져온 결과는 자동으로 DTO가 되지 않는다.
ResultSet에서 꺼낸 컬럼 값을 DTO의 어떤 필드에 넣을지를 사람이 코드로 지정해야 한다.
5) 그 역할을 하는 클래스가 RowMapper이고 “강제로 (규칙대로) 만들기 위해 implements 한다”
“그 이야기를 해줄 클래스”를 만들고 그걸 로우매퍼 (RowMapper) 라고 부른다고 정리한다.
그리고 중요한 포인트가 이어진다.
- “그냥 막 만들면 안 되고 JDBC 템플릿이 쓸 수 있게끔 줘야 된다.”
- “강제해야 한다.”
그래서 수업에서는 RowMapper<BoardDTO>를 implements 해서 JdbcTemplate이 요구하는 형태로 만들게 된다.
“메서드 강제가 필요하므로 인터페이스를 추가하여 구현하면 된다”고 정리한다.
6) PlusBoardDAO에서 단건 / 리스트 조회 구현
- 단건 (select one) → queryForObject()
- 리스트 (select all) → query()
public BoardDTO getBoard(BoardDTO dto) {
return jdbcTemplate.queryForObject(SELECT_ONE, new BoardRowMapper(), dto.getBid());
}
public List<BoardDTO> getBoardList(BoardDTO dto){
return jdbcTemplate.query(SELECT_ALL, new BoardRowMapper());
}
7) BoardRowMapper에서 “컬럼 → DTO 필드”를 직접 지정한다
class BoardRowMapper implements RowMapper<BoardDTO> {
@Override
public BoardDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
BoardDTO data = new BoardDTO();
data.setBid(rs.getInt("BID"));
data.setTitle(rs.getString("TITLE"));
data.setWriter(rs.getString("WRITER"));
data.setContent(rs.getString("CONTENT"));
data.setRegdate(rs.getDate("REGDATE"));
data.setCnt(rs.getInt("CNT"));
return data;
}
}
PlusBoardDAO 아래에 BoardRowMapper를 같은 파일에 두었지만 내부 클래스가 아니라 그냥 별도의 클래스를 같은 파일에 둔 형태이다.
8) 리스트 반환은 query()를 쓴다 (파라미터 없으면 안 넣는다).
- “리스트 반환할 때는 query라는 메서드를 쓴다.”
- “select all이고 파라미터 줄 게 없으면 안 쓴다.”
- “어떻게 반환할지만 알려주면 알아서 리스트 반환해 준다.”
10) RowMapper는 하나만 있는 게 아니다: ResultSet (결과 모양)이 다르면 RowMapper도 여러 개
조회 결과 컬럼 구성이 달라져서 DTO에 채워 넣는 방식이 달라지면 그에 맞는 RowMapper를 별도로 만든다.
11) 콘솔 실행에서 단건 조회 전에 조회수 증가 (update)를 먼저 호출한다
“2. 1개출력”을 선택했을 때 흐름이 이렇게 되어 있다.
- bid 입력
- updateBoard(dto) 호출 (조회수 증가)
- getBoard(dto) 호출 (단건 조회 후 출력)
else if(command == 2) {
System.out.print("출력할 글 번호 입력 >> ");
BoardDTO dto = new BoardDTO();
dto.setBid(sc.nextInt());
boardService.updateBoard(dto);
System.out.println(boardService.getBoard(dto));
}
- DB 변경 (CUD): update() 사용
- 단건 조회 (select one): queryForObject() 사용
- 리스트 조회 (select all): query() 사용, 파라미터 없으면 생략
- SELECT는 반환이 있으므로 “컬럼 → DTO 필드 매핑”을 직접 지정해야 한다
- 그 매핑 규칙을 담는 클래스가 RowMapper이고 JdbcTemplate이 쓰게 하려면 인터페이스 구현 (강제)이 필요하다
- 결과 모양이 다르면 RowMapper도 여러 개가 될 수 있다
'수업 복습' 카테고리의 다른 글
| BoardDAO를 MyBatis로 리팩토링 실습 과제 (0) | 2026.02.09 |
|---|---|
| JDBC DAO에서 MyBatis로 리팩토링 (0) | 2026.02.09 |
| 스프링에서의 JDBC 정리 (0) | 2026.01.28 |
| Spring AOP를 어노테이션 (@)으로 전환하는 흐름 정리 (0) | 2026.01.27 |
| 바인드 변수로 핵심관심 정보 뽑아오기 (0) | 2026.01.26 |