ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] RowMapper<T> mapRow(), ResultSet를 객체로 반환
    legacy/Spring 2023. 7. 4. 14:39

     

    JdbcTemplate를 사용하다 보면 RowMapper 인터페이스를 본 적이 있을 것이다.

    자세히 알고 쓰지 않으면 잘못된 사용을 할 수도 있으니 주의하자

     

    JdbcTemplate 사용 전

    우리는 지금까지 DB에 select문을 날려서 결과 값으로 ResultSet을 받아서 사용해 왔었다. 아래와 코드를 확인하자.

     

    ResultSet 사용

    public Member findById(String memberId) throws SQLException {
        String sql = "select * from member where member_id = ?";
    
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
    
        try {
        	생략...
            
            rs = pstmt.executeQuery();
    
            if (rs.next()) {
                Member member = new Member(rs.getString("member_id"), rs.getInt("money"));
                return member;
            } 
            
        	생략...
    }

     

    근데 JdbcTemplate를 사용하면서 템플릿이 알아서 결과를 자동으로 바인딩 해줬다.

    (이게 무슨 말인지 모르겠다면 여기를 참고하자)

     

    JdbcTemplate에 정의된 메서드

    // 코드 일부만 가져왔다.
    
    @Override
    public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException {
        return result(query(sql, new RowMapperResultSetExtractor<>(rowMapper)));
    }
    
    @Override
    @Nullable
    public <T> T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException {
        List<T> results = query(sql, rowMapper);
        return DataAccessUtils.nullableSingleResult(results);
    }

    어쨌든 우리의 목표는 db에 select문을 날리고 값을 반환받는 것이다.


    RowMapper<T>가 뭔데?

    @FunctionalInterface
    public interface RowMapper<T> {
    
    	@Nullable
    	T mapRow(ResultSet rs, int rowNum) throws SQLException;
    }

    RowMapper에는 한 개의 메서드가 존재한다. 그게 바로 mapRow이다. 

    mapRow()는 db로부터 반환받은 ResultSet을 T타입 객체로 변환해준다. 

     

    mapRow() 매개변수

    • ResultSet rs : db 조회 결과 반환 값
    • rowNum : 조회된 행의 개수

    아래를 보면 람다식을 사용하여 mapRow() 메서드를 사용하고 있다. 

    마치 ResultSet을 사용했던 것처럼 그대로 사용하면 된다.

    public Member findById(String memberId) {
        String sql = "select * from member where member_id = ?";
        return jdbcTemplate.queryForObject(sql, (rs, rowNum) -> {
            Member member = new Member();
            member.setMemberId(rs.getString("member_id"));
            member.setMoney(rs.getInt("money"));
            return member;
        }, memberId);
    }

    결론

    JdbcTemplate를 사용하기 전에는 직접 ResultSet를 받아 사용한다.

    JdbcTemplate를 사용하면 RowMapper를 적절히 사용하면 된다.

Designed by Tistory.