[Spring] JdbcTemplate

SCY·2023년 2월 22일
0

옛날에는 자바와 DB를 연결하기 위해서 JDBC를 사용해야만 했다. 나 또한 작년 학교 과제에서 PostgreSQL과 JDBC를 이용한 경험이 있다... 이번 스프링 강의를 들으며 JdbcTemplate이라는 아주 유용한 클래스를 알게 되었다. JdbcTemplate의 위력을 느끼기 위해 JDBC를 간단히 맛보자.

public List<Member> findAll() {
	String sql = "select * from member";
    
	Connection conn = null;
 	PreparedStatement pstmt = null;
 	ResultSet rs = null;
    
 	try {
 		conn = getConnection();
		pstmt = conn.prepareStatement(sql);
        
 		rs = pstmt.executeQuery();
        
 		List<Member> members = new ArrayList<>();
 		while(rs.next()) {
 			Member member = new Member();
 			member.setId(rs.getLong("id"));
 			member.setName(rs.getString("name"));
 			members.add(member);
 			}
            
        return members;
 	} catch (Exception e) {
 		throw new IllegalStateException(e);
 	} finally {
 		close(conn, pstmt, rs);
 	}
}

위 코드는 JDBC를 이용한 전체 멤버 조회 코드이다. 삽입, id로 조회, name으로 조회 등 모든 기능을 위와 같이 하나하나 작성해야 한다. 불필요하게 반복되는 부분이 너무나도 많고 복잡하다.

이를 보완하기 위해 JdbcTemplate이 탄생했다.
스프링에서 제공하는 클래스로 JDBC 코어 패키지의 중심 클래스이다. JdbcTemplate 외에도 NamedParameterJdbcTemplate, SimpleJdbcInsert, SimpleJdbcCall 등의 클래스들이 존재한다.

JdbcTemplate을 사용할 때는 아래와 같이 DataSource를 항상 스프링 컨테이너에서 빈으로 구성해야 한다.

private final DataSource dataSource;

    public SpringConfig(DataSource dataSource) {
        this.dataSource = dataSource;
    }

🌱 queryForObject()

Integer로 반환되는 쿼리

/* 멤버 수 조회 */
int result = jt.queryForObject("SELECT count(*) FROM members", Integer.class);

String으로 반환되는 쿼리

/* 해당 id("spring")를 가진 멤버의 이름 조회 */
String result = jt.queryForObject("SELECT name FROM members WHERE id = ?", "spring", String.class);

객체를 반환하는 쿼리

/* 해당 id(spring)를 가진 멤버 조회 */
Member result = jt.queryForObject("SELECT * FROM members WHERE id = ?", "spring", memberRowMapper());

private RowMapper<Member> memberRowMapper() {
    return (rs, rowNum) -> {
        Member member = new Member();
        
        member.setId(rs.getString("id"));
        member.setName(rs.getString("name"));
        member.setPw(rs.getString("pw"));
        
        return member;
    };
}

객체를 조회할 때는 RowMapper를 활용한다. 여기서는 memberRowMapper()로 따로 정의해주었다. 이는 데이터베이스의 반환 결과인 ResultSet을 Member 객체로 변환해 준다. Interger, String은 컴파일러가 해당 타입에 맞게 알아서 매핑해주지만 Member는 우리가 생성한 객체이기 때문에 직접 Mapping Logic을 구현해야 한다.

🌱 query()

여러 객체를 반환하는 쿼리

List<Member> result = jt.query("SELECT * FROM members", memberRowMapper());

/* memberRowMapper()는 위와 같이 생성 */

🌱 update()

실행 시 SQL 실행 결과에 영향받은 행의 수를 int로 반환한다.

/* 멤버 등록 */
jt.update("INSERT INTO members(id, pw, name) VALUES(?, ?)",
                "spring", "1234", "Jenny");
/* 멤버 수정 */
jt.update("UPDATE members SET name = ? WHERE id = ?",
				"Jenny", "winter");
/* 멤버 삭제 */
jt.update("DELETE FROM members WHERE id = ?",
				"winter");

🌱 execute()

임의의 SQL을 실행할 때는 위 메서드를 사용할 수 있다.

profile
성장 중독 | 서버, 데이터, 정보 보안을 공부합니다.

0개의 댓글