JdbcTemplate - query메서드

hyungjunn·2024년 2월 25일

Spring 번역

목록 보기
1/1

jdbcTemplate

query()

@GetMapping("/user")
    public List<UserResponse> getUsers() {
        String sql = "SELECT * FROM user"; 
        return jdbcTemplate.query(sql, new RowMapper<UserResponse>() {
            @Override
            public UserResponse mapRow(ResultSet rs, int rowNum) throws SQLException {
                long id = rs.getLong("id");
                String name = rs.getString("name");
                int age = rs.getInt("age");
                return new UserResponse(id, new User(name, age));
            }
        });
    }

처음 query메서드

  • method return type : List<T>
  • method parameter : String sql, RowMapper<T> rowMapper

RowMapper<T>란?

ResultSet의 행들을 행단위로 매핑하기 위해 JdbcTemplate에 의해 사용되어지는 interface이다. 이 interface의 구현은 각각의 행을 결과 객체에 매핑하는 실제 작업을 수행하지만 예외 핸들링에 대한 걱정은 필요하지 않다. SQLExceptions가 JdbcTemplate의 호출로 인해 잡힐 것이고 처리될 것이다.

흔히 JdbcTemplate의 쿼리 메서드 또는 저장된 프로시저의 매개변수에 사용된다. RowMapper 객체는 일반적으로 상태가 없고 재사용할 수 있으며 단일 장소에서 행-매핑 로직을 구현하는데에 적합한 선택이다.

또는, org.springframwork.jdbc.object.MappingSqlQuery를 jdbc.object package에서 subclassing을 고려해보아라. JdbcTemplate와 RowMapper 객체를 분리하는 대신 실행가능한 쿼리 객체 (행-매핑 로직을 포함하는) 를 해당 스타일로 만들 수 있다.

RowMapper - mapRow method

구현들은 ResultSet안에서 데이터의 각 행을 매핑하기 위해 이 방법을 구현해야 한다. 이 방법은 ResultSet에서 next()를 호출하면 안되고, 오로지 현재 행의 값들을 매핑하는 것으로만 되어있다.

Params:

  • rs - 매핑할 ResultSet(현재 행에 대해 사전초기화됨)
  • rowNum - 현재 행이 몇번 째인지

Returns: 현재 행(null일 수도 있음)에 대한 결과 객체, T타입을 반환

Throws: SQLException - 만약 열 값을 가져오는 동안 SQLException이 발생한 경우(SQLException을 잡을 필요 없음)

result()

null인지 확인하고 다시 result 반환

두번째 query()

// Callback to execute the query.
class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
	@Override
	@Nullable
	public T doInStatement(Statement stmt) throws SQLException {
		ResultSet rs = null;
		try {
			rs = stmt.executeQuery(sql); // sql을 실행한 쿼리를 rs에 담는다
			return rse.extractData(rs); // rs를 추출하여 리턴한다
		}
		finally {
			JdbcUtils.closeResultSet(rs);
		}
	}
	@Override
	public String getSql() {
			return sql;
	}
}

QueryStatementCallback 객체를 실행하는 것을 리턴

execute 메서드

  • 반환 타입 : T
  • 반환값 : result
  • 매개 변수 : StatementCallback<T>, boolean closeResources

try {
			stmt = con.createStatement(); // database에 SQL문을 보내기 위한 'Statement' 객체를 생성한다
			applyStatementSettings(stmt); // stmt객체에 여러 설정을 적용한다
			T result = action.doInStatement(stmt); // stmt을 실행한 결과 result에 담는다
			handleWarnings(stmt); // 에러를 핸들링한다
			return result;
		}

두번째 query()의 return값

return rse.extractData(rs);

rs : new RowMapperResultSetExtractor<>(rowMapper)의 객체

rs가 extractData(rs)

  1. 행이 0보다 크면 List에 담고

  2. 다음 행이 없을 때가지 그 List에 rowMapper.mapRow(rs, rowNum++)을 담는다

  3. 그 List를 반환한다

  • rowNum을 조작하여 원하는 값만 얻어낼 수도 있음
  • 라이브러리를 만드는 입장에서 여러 사람이 사용할 수도 있어야 하기 때문에 이렇게 사용자 정의를 할 수 있게 하는 기능을 넣음

참고: 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]

0개의 댓글