• 데이터 접근 객체
: 데이터베이스 작업 추상화 & 캡슐화 => 데이터 소스 접근과 비즈니스 로직 분리
• 재사용성
: 코드 재사용 도와줌, 다양한 데이터 소스에 대해 일관된 인터페이스 제공
• 유지보수성
: 데이터 접근 로직이 한 곳에 집중돼 있어 유지보수 용이, 변경 사항 쉽게 적용 가능
• 코드 간소화
: 반복적인 JDBC 코드 줄여줌으로써 개발자는 핵심 비즈니스 로직에 집중 가능
• 예외 처리 개선
: checked 예외를 unchecked 예외로 변경 => 예외 처리의 유연성 상승
• 테스트 용이성
: 의존성 주입 통해 DAO를 쉽게 모의 객체로 대체 가능 => 단위 테스트 용이
메소드의 구조 정의하고 일부 단계를 하위 클래스에서 구현하도록 하는 디자인 패턴 => 구조 변경 없이 특정 단계 재정의 가능 => 반복적인 코드 효과적으로 추상화 & 재사용성 증가
RowMapper, ResultSetExtractor 등의 콜백 사용 => 결과 매핑 커스터마이즈
batchUpdate 메서드로 대량 데이터 처리 효율적으로 수행
JDBC 및 데이터소스 지원 위한 핵심 의존성
트랜잭션 관리 위한 의존성 (spring 4.3.3 버전부터 spring-jdbc에 포함)
사용하는 데이터베이스에 맞는 JDBC 드라이버 추가해야 함
Maven 또는 Gradle에 spring-jdbc 의존성 추가
데이터베이스 연결 정보 포함한 DataSource 구성
◦ DataSource 빈 정의
XML 또는 Java 설정으로 DataSource 빈 정의
◦ 연결 풀(connection pool) 설정
HikariCP와 같은 연결 풀 사용하여 성능 최적화 => DB 연결 효율적 관리
◦ 프로퍼티 외부화
데이터베이스 연결 정보 properties 파일로 분리 => 환경별 설정 용이
DataSource 이용해 JdbcTemplate 객체 생성
• 코드 중복
: 연결, 명령문 생성, 결과 처리 등의 코드 반복 => 가독성 하락
• 예외 처리 복잡성
: JDBC의 checked 예외 처리 번거롭고 코드 복잡
• 자원 관리 부담
: Connection, Statement, ResultSet 등의 자원 수동으로 관리해야 함 => 메모리 낭비의 위험
• 객체 지향 데이터 모델링 및 영속성 관리 제공하는 표준 API
• 복잡한 SQL 쿼리 작성 자동화, 객체지향적 프로그래밍 방식 지원
• 데이터베이스와 직접 통신하는 Java API
• SQL 쿼리 직접 작성 및 실행해야 함, 개발자가 DB 관련 코드 직접 관리해야 함
• 자원 관리 자동화
: JDBC 템플릿이 연결 열기와 닫기 관리 => 개발자 부담 축소
• 예외 변환
: JDBC 예외를 스프링의 DataAccessException으로 변환 => 예외 처리 일관
• 코드 간소화
: 반복적인 코드 제거하여 핵심 로직에 집중 => 생산성 향상
원자성 (Atomicity)
트랜잭션의 모든 연산이 성공하거나 모두 실패해야 함 => 데이터 일관성 유지
일관성 (Consistency)
트랜잭션 전후로 데이터베이스가 일관된 상태 유지 => 데이터 무결성 보장
격리성 (Isolation)
동시에 실행되는 트랜잭션들이 서로 영향 주지 않게 하여 동시성 문제 방지
지속성 (Durability)
성공적으로 완료된 트랜잭션의 결과는 영구적으로 반영돼야 하므로 데이터의 안정성 보장
• 데이터 일관성
• 에러 복구
• 동시성 제어
DataSourceTransactionManager 빈 정의 => JDBC 기반 트랜잭션 관리@EnableTransactionManagement@Transactional• 어떤 트랜잭션이 동작 중인 과정에서 다른 트랜잭션 실행할 경우 어떻게 처리하는지에 대한 개념
◦ 메서드 호출: 한 메서드가 다른 메서드 부를 때, 트랜잭션이 함께 이어져 호출
◦ 안전한 데이터 처리: 작업이 하나로 묶여 처리되므로 문제 발생 시 모든 작업 취소 통해 안전하게 처리 가능
◦ 쉬운 설정: 스프링에서 제공하는 기능으로 간단히 설정 가능
◦ 실무 활용: 여러 데이터 작업 안전하게 처리해야 할 때 유용
REQUIRED
: 기존 트랜잭션 있으면 참여하고 없으면 새로 생성 (가장 흔히 사용되는 기본 설정)
REQUIRES_NEW
: 항상 새로운 트랜잭션 시작, 기존 트랜잭션은 일시 중단
NESTED
: 기존 트랜잭션 내에서 중첩 트랜잭션 실행, 부분적 롤백 가능
SUPPORTS
: 트랜잭션 있으면 참여, 없어도 비트랜잭션으로 실행
@Transactional 어노테이션의 propagation 속성으로 트랜지션 전파 방식 지정RuntimeException은 기본적으로 롤백 유발rollbackFor, noRollbackFor 속성으로 롤백 규칙 세밀하게 제어 가능update() 메서드 사용
• INSERT 쿼리 실행하여 데이터 삽입 가능
파라미터 바인딩
• '?' 플레이스홀더 사용하여 악의적인 SQL injection 방지 가능
KeyHolder 사용
• 자동 생성된 키 값 얻기 위해 사용
• 특히 KeyHolder는 새로 삽입된 데이터의 기본 키 값을 편리하게 가져올 수 있도록 도와줌
queryForObject()
• 단일 결과 조회 시 사용
• RowMapper 통해 결과 객체로 매핑
query()
• 여러 결과 리스트로 조회할 때 사용
• 복잡한 객체 매핑에 유용
RowMapper 구현
• ResultSet의 데이터 객체로 변환하는 로직 정의
• 재사용 가능한 매핑 전략 제공
update() 메서드
• CREATE 연산과 유사하게 UPDATE 쿼리 실행에도 사용
다중 파라미터
• 여러 개의 파라미터 순서대로 전달
• 복잡한 UPDATE문 실행 시 유리
배치 업데이트
• batchUpdate() 메서드로 여러 레코드 한번에 업데이트 가능
• 대량 데이터 처리 시 성능 향상
update() 사용
• 영향받은 행의 수 반환받아 삭제 여부 확인 가능
조건부 삭제
• WHERE절 사용하여 특정 조건에 맞는 데이터만 안전하게 삭제
예외 처리
• DataAccessException을 catch하여 삭제 중 발생할 수 있는 오류 처리

config/TrnasactionConfig
지난번에 JPA로 과제 했으므로 얘도 JPA에 맞게 작성

repository/UserDao
findAll(), findById(ID id), save(T entity), deleteById(ID id), existsById(ID id) 등등 JPA의 JpaRepository 인터페이스에서 기본적으로 제공해주기 때문에 간단하게만 작성

service/UserService에
DB 비우는 코드, email로 유저 찾는 코드, 닉네임 중복 여부 확인 코드 작성

controller/UserController에
email로 사용자 찾아 있으면 200 반환, 없으면 404 반환하는 코드 추가

test/java/week5/service/UserServiceTest 코드 작성

오류가 나서 domail/User에 기본 생성자 & 모든 필드 초기화하는 생성자 추가하여 해결
• https://www.h2database.com 접속하여 h2 데이터베이스 설치 및 압축 해제

• 터미널에서 h2\bin 들어가서 ./h2.bat 입력


• member 테이블 생성

• 요소 추가
• build.gradle에
implementation 'com.h2database:h2',
implementation 'org.springframework.boot:spring-boot-starter-jdbc' 추가
• study.hello_spring/repository/JdbcMemberRepository 코드 작성
• study.hello_spring/service/SpringConfig 코드 수정
◦ DataSource는 데이터베이스 커넥션을 획득할 때 사용하는 객체
◦ 스프링 부트는 데이터베이스 커넥션 정보를 바탕으로 DataSource를 생성하고 스프링 빈으로 만들어두기에 DI를 받을 수 있음

• study.hello_spring/service/MemberServiceIntegrationTest 코드 작성
◦ @SpringBootTest: 스프링 컨테이너와 테스트를 함께 실행
◦ @Transactional: 테스트 케이스에 이 애노테이션이 있으면 테스트 시작 전에 트랜잭션을 시작하고, 테스트 완료 후에 항상 롤백 => 이렇게 하면 DB에 데이터가 남지 않으므로 다음 테스트에 영향을 주지 않음