스택큐힙리스트

자바 스프링 개발 시작하기 - 11일차 Spring Data JPA로 데이터 접근 레이어 설계 본문

개발

자바 스프링 개발 시작하기 - 11일차 Spring Data JPA로 데이터 접근 레이어 설계

스택큐힙리스트 2025. 7. 18. 18:15
반응형

1. 왜 ‘데이터 접근 레이어’인가?

Spring Boot 서비스가 커질수록 Entity → Repository → Service 삼단 구조는 유지보수와 확장성을 지켜주는 필수 뼈대입니다.

  • Entity: 데이터베이스 테이블과 1 : 1로 매핑되는 도메인 모델
  • Repository: Spring Data JPA가 만들어 주는 CRUD + 확장 쿼리 메서드
  • Service: 트랜잭션 경계에서 비즈니스 로직 담당

2. 의존성 및 기본 설정

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly   'com.h2database:h2'         // 개발·테스트
runtimeOnly   'com.mysql:mysql-connector-j' // 운영

application.yml 에서 프로필로 H2↔MySQL 전환:

spring:
  profiles:
    active: dev          # dev ↔ prod
---
spring:
  config:
    activate:
      on-profile: dev
  datasource:
    url: jdbc:h2:mem:testdb
    driver-class-name: org.h2.Driver
    username: sa
    password:
---
spring:
  config:
    activate:
      on-profile: prod
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: secret

3. Entity 정의 - JPA 어노테이션 최소화

@Entity @Table(name = "posts")
@Getter @NoArgsConstructor(access = PROTECTED)
public class Post {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 150)
    private String title;

    @Lob
    private String content;

    public Post(String title, String content) {
        this.title   = title;
        this.content = content;
    }
}

4. Repository 인터페이스 - 코드 한 줄로 CRUD 완성

public interface PostRepository extends JpaRepository<Post, Long> {
    // 관례 기반 쿼리 메서드
    List<Post> findByTitleContainingOrderByIdDesc(String keyword);
}

구현체는 Spring Data JPA가 런타임에 자동 생성하여 빈으로 주입합니다.

5. Service 계층 - 트랜잭션과 DTO 매핑

@Service @RequiredArgsConstructor
@Transactional(readOnly = true)
public class PostService {
    private final PostRepository postRepository;

    @Transactional
    public Long write(PostWriteRequest dto) {
        Post saved = postRepository.save(dto.toEntity());
        return saved.getId();
    }

    public List<PostSimpleResponse> search(String keyword) {
        return postRepository.findByTitleContainingOrderByIdDesc(keyword)
                             .stream()
                             .map(PostSimpleResponse::from)
                             .toList();
    }
}
  • @Transactional(readOnly = true): 조회 트랜잭션 최적화
  • DTO로 엔티티 노출을 막아 계층 간 결합도를 최소화합니다.

6. 빠른 테스트: H2 콘솔 & 테스트 슬라이스

  • spring.h2.console.enabled=true 로 in-memory DB 데이터 확인
  • @DataJpaTest 로 Repository 단위 테스트 시 H2 자동 사용

7. 마무리 & 다음 스텝

오늘은 Spring Data JPA 로 H2와 MySQL을 넘나들며 엔티티→레포→서비스 구조를 완성했습니다.
이제 복잡한 조회 쿼리는 Querydsl 또는 Specification 으로, 쓰기 성능은 Bulk Insert, Batch Size 로 최적화해 보세요!

반응형
Comments