JDBC( Java Database Connectivity ) :
。자바(Java)에서DB에 접속할 수 있도록 연결하는API
▶Java Application에서DB에 접근하여 사용자가 작성한SQL을 통해SELECT , INSERT , UPDATE , DELETE수행.
。JPA는속도가 느리므로 주로 대량의 데이터를 다루는 작업이 필요할 때SQL을 활용해 사용하는 방식
Spring Data JDBC
。Spring Framework에서 제공하는JDBC를추상화한모듈
▶추상화를 통해 기존JDBC로DB와 상호작용하는 과정을 단순화implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
(위 : JDBC / 아래 : Spring JDBC )
▶JDBC를 추상화하여DB와 연결 시 기존JDBC보다 훨씬 더 적고 간결하게 작성하여 활용이 가능
JdbcTemplate:
。Spring JDBC를 간소화하고 편리하게 활용하여DB와상호작용할 수 있도록 돕는클래스
▶DB연결,Query 실행,결과처리,예외처리등을 간편하게 처리private JdbcTemplate springJdbcTemplate;▶
JdbcTemplate 객체선언 및의존성주입후static method를 통해조작을 수행
JdbcTemplate static Method
。update(),queryForObject(),query()가 존재
JdbcTemplate객체.update(SQL_query,매개변수값):
。JdbcTemplateclass의updatemethod를 통해INSERT / UPDATE / DELETE의 SQL query를 활용하여 DB 수정.
。sql의 매개변수가 다음처럼?로 표현된 경우,updatemethod 매개변수에 sql 매개변수에 입력될 data를 정의.String sql = "insert into course values(?,?,?)"; JdbcTemplate객체.update(sql, 1 , 2 , 3)
JDBC를 통해데이터가져오기
- 활용예시
public record MemberReadResponse (String name, LocalDate birthday){ }。 Return된
SQL행 데이터를 포함할 Template 혹은DTO역할의 Class.
▶Record이므로불변객체로 지정
▶queryForObject()에 의한 단일행데이터 반환 시 단일 Class instance 반환.
▶query()에 의한 여러행데이터 반환 시List<Class객체>로 반환.
JdbcTemplate객체.queryForObject(SQL, new MemberRowMapper() , 매개변수값 ):
。단일행(Row) 결과를 반환하는SELECTQuery를 실행 시 사용.
▶SELECTquery를 통해 추출된 데이터가Spring Beaninstance로 변환되어 반환.
▶ 여러 행 결과 반환 시jdbctemplate객체.query()사용.
。개발자는 SQL 작성 및 전달할 매개변수를 직접 정의하여 mapping을 수행.
。transaction을 위한connection 동기화및Spring 예외 변환기를 자동 실행함.
。결과값을 가져오게될 경우,SpringBeanclass에서 반드시setter method를 정의.public MemberReadResponse read(int id){ String selectSql = """ select name, birthday from member where loginid = ?; """; return jdbcTemplate.queryForObject(selectSql,new MemberRowMapper(),id ); }.
JdbcTemplate객체.query(SQL, 매개변수포함Object배열 , RowMapper 객체)
。DB에서 여러행(Row) 결과를 반환하는SELECTQuery를 실행 시 사용.
▶RowMapper<Type>을 사용하여 결과를 Class Instance로 Mappingimport org.springframework.jdbc.core.RowMapper; import com.kt.shopping.dto.MemberReadResponse; public class MemberRowMapper implements RowMapper<MemberReadResponse> { public MemberReadResponse mapRow(ResultSet rs, int rowNum) throws SQLException { MemberReadResponse member = new MemberReadResponse( rs.getString("name"), LocalDate.parse(rs.getString("birthday"))); return member; } }public List<MemberReadResponse> readAll(){ String selectSqlAll = """ select name, birthday from member; """; return jdbcTemplate.query(selectSqlAll,new MemberRowMapper()); }
RowMapper<ClassType>
。Spring JDBC에서 SQL Query의 결과를 Class 객체로 변환하는Interface.
▶JdbcTemplate객체.query()에서 사용되며 각행을 원하는Class객체로 Mapping.
。해당인터페이스의함수형 인터페이스(메서드 레벨) 또는구현체(클래스 레벨)를JdbcTemplate객체.query()의 매개변수로 전달
。매개변수로 전달되는ResultSet객체를 이용하여 SQL의 각Column을Template,DTO역할의 Class 객체의 Field로 Mapping.
▶record를 통해생성자에 전달하여불변객체의 생성 후 반환
클래스 레벨에서RowMapper선언 및 활용
。RowMapper 인터페이스를 상속한클래스를jdbcTemplate.query()의 인자에객체생성하여 전달
▶mapRow() 구현메소드를 구현import java.sql.ResultSet; import java.sql.SQLException; import java.time.LocalDate; import org.springframework.jdbc.core.RowMapper; import com.kt.shopping.dto.MemberReadResponse; public class MemberRowMapper implements RowMapper<MemberReadResponse> { public MemberReadResponse mapRow(ResultSet rs, int rowNum) throws SQLException { return new MemberReadResponse( // SQL 데이터의 Column을 rs객체를 통해 가져와서 // template 역할 Class의 Field로 Mapping. rs.getString("name"), LocalDate.parse(rs.getString("birthday"))); } }public MemberReadResponse read(int id){ String selectSql = """ select name, email, mobile, gender , birthday from member where loginid = ?; """; return jdbcTemplate.queryForObject(selectSql,new MemberRowMapper(),id ); }
메서드 레벨에서RowMapper선언
。함수형 인터페이스( =람다식)을 반환하도록 정의하여jdbcTemplate.query()의 인자에함수형 인터페이스를 전달// 로우매퍼를 메서드 레벨에서 선언 private RowMapper<MemberReadCredential> rowMapperForPassword(){ return (rs, rowNum)-> mapToPassword(rs); } private MemberReadCredential mapToPassword(ResultSet rs) throws SQLException { return new MemberReadCredential( rs.getString("id"), rs.getString("password")); }