[Spring] 2주차 - JPA로 데이터베이스 다루기

smjan27·2021년 10월 10일
0

Spring Boot

목록 보기
6/9

스프링 부트와 AWS로 혼자 구현하는 웹 서비스 - 03장

🚨 지난 주에 프로젝트 폴더를 옮긴 후 다시 인텔리제이를 켜니 이런 경고창이 나타났다.

.idea/vcs.xml 파일을 삭제하고 창을 닫았다가 다시 실행하니 문제가 해결되었다.

JPA

관계형 데이터베이스는 SQL만 인식할 수 있음
-> SQL 코드 과잉, SQL 종속 문제

객체지향 프로그래밍 언어와 관계형 데이터베이스를 중간에서 패러다임 일치 시켜주기 위한 기술

  • 인터페이스인 JPA를 사용하려면 구현체가 필요 (Hibernate, Eclipse 등)
  • 본 교재에서는 구현체들을 쉽게 사용하고자 추상화시킨 Spring Data JPA라는 모듈을 통해 JPA 다룰 예정 (구현체 및 저장소 교체 용이)
  • 관계: JPA <- Hibernate <- Spring Data JPA
  • crud 쿼리 작성 필요 없음
  • 부모-자식 관계 표현, 1:N 관계 표현 등 객체지향 프로그래밍 쉽게 가능

요구사항 분석

  • 게시판 기능
    • 게시글 조회/등록/수정/삭제
  • 회원 기능
    • 구글/네이버 로그인
    • 로그인한 사용자 글 작성 권한
    • 본인 작성 글에 대한 권한 관리

프로젝트에 Spring Data JPA 적용

build.gradle

(수정 후 다시 로드해야 함)

dependencies {
    ...
    // Spring Data JPA 추상화 라이브러리
    // 스프링 부트 버전에 맞춰 자동으로 JPA 관련 라이브러리 버전 관리
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    // h2: 인메모리 관계형 데이터베이스
    // 메모리에서 실행, 재시작할 때마다 초기화 -> 테스트 용도
    // JPA 테스트, 로컬환경 구동에 사용
    compile('com.h2database:h2')
    ...

main/java/com.name.springboot/domain 패키지 생성

  • 게시글, 댓글, 회원, 정산, 결제 등 소프트웨어에 대한 요구사항(도메인)을 담을 패키지

domain/posts/Posts 클래스 생성

  • JPA에서 제공하는 어노테이션
    • @Entity
    • @Id
    • @GeneratedValue
    • @Column
  • lombok 라이브러리의 어노테이션(@NoargsConstructor, @Getter, @Builder): 코드 변경량 최소화
  • 주의: Setter 메소드 만들지 않음
  • 생성자를 통해 최종값을 채운 후 데이터베이스에 삽입
  • 값 변경 필요한 경우 해당 이벤트에 맞는 public 메소드 호출
  • 본 교재에서는 생성자 대신 @Builder를 통해 제공되는 빌더 클래스 사용 -> 어느 필드에 어떤 값을 채워야 할지 명확하게 인지 가능

Entity

JPA의 어노테이션, 테이블과 대응하는 클래스

domain/posts/PostsRepository 인터페이스 생성

  • 역할: Posts 클래스로 DB 접근하게 해줌(DB Layer 접근자)
  • JPA에서는 Repository라고 부르며, 인터페이스로 생성
  • JpaRepository<Entity 클래스, PK 타입>을 상속하면 CRUD 메소드 자동 생성

테스트

🚨 Cannot resolve symbol 'assertThat' 문제는 아래의 코드를 추가하여 해결

import static org.assertj.core.api.Assertions.assertThat;

테스트 코드에서의 given, when, then 패턴이란?

  • given: 준비 - 객체 생성
  • when: 실행 - 실제로 액션을 하는 테스트를 실행하는 과정
  • then: 검증 - 해당 객체의 응답값 검사, 테스트 검증

출처: https://codecrafting.tistory.com/2

main/resources/application.properties 생성

  • 역할: 실제로 실행된 쿼리를 로그로 볼 수 있게 해줌
spring.jpa.show_sql=true
// 출력되는 쿼리 로그를 H2 -> MySQL 버전으로 변경
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect

등록/수정/조회 API 생성

필요한 클래스
1. Request 데이터를 받을 Dto
2. API 요청을 받을 Controller
3. 트랜잭션, 도메인 기능 간의 순서를 보장하는 Service

Spring 웹 계층

  • Web Layer
    • 컨트롤러(@Controller)와 JSP/Freemaker 등 뷰 템플릿 영역
    • 필터(@Filter), 인터셉터, 컨트롤러 어드바이스(@ControllerAdvice) 등 외부 요청과 응답에 대한 전반적인 영역
  • Service Layer
    • @Service에 사용되는 서비스 영역
    • 일반적으로 Controller와 Dao의 중간 영역에서 사용됨
    • @Transactionl이 사용되어야 하는 영역
  • Repository Layer
    • DB와 같이 데이터 저장소에 접근하는 영역
  • Dtos(Data Transfer Object)
    • 계층 간 데이터 교환을 위한 객체들의 영역
    • 예) 뷰 템플릿 엔진에서 사용될 객체, Repository Layer에서 결과로 넘겨준 객체
  • Domain Model
    • 개발 대상(도메인)을 모든 사람이 동일한 관점에서 이해/공유할 수 있도록 단순화시킨 것
    • 예) 택시 앱의 배차, 탑승, 요금 등
    • @Entity가 사용된 영역
    • 비즈니스 처리 담당

  • domain: 비즈니스 처리를 담당하며 Entity가 사용되는 영역 - Entity 영역

    • Posts: 실제 DB의 테이블과 매칭될 클래스 (Entity 클래스)
    • Repository: DB와 같이 데이터 저장소에 접근하는 영역 클래스 - DB 접근 영역
      • PostsRepository : Posts 클래스로 DB에 접근하게 해주는 인터페이스 (DB Layer 접근자)
  • service: 트랜잭션, 도메인 간의 순서를 보장하는 영역 - 순서 보장 영역

    • PostsService: 순서 보장을 위한 service
  • web : API의 요청을 받는 컨트롤러 등의 뷰 템플릿 영역, 외부 요청과 응답에 대한 전반적인 영역 - 요청을 받는 영역

    • PostsApiController: API를 요청받을 컨트롤러
    • dto: 계층 간의 데이터 교환을 위한 객체들의 영역, request 데이터를 받음 - 데이터 교환, 변경을 위한 영역
      • PostsReponseDto: 조회 기능을 위한 Dto
      • PostsSaveRequestDto: 등록 기능을 위한 Dto
      • PostsUpdateRequestDto: 수정 기능을 위한 Dto

요약

  • Domain에서 엔티티 생성 및 테이블 생성, Repository를 통해 데이터베이스 접근
  • Service는 트랜잭션, 도메인 기능 간의 순서 보장
  • Web의 controller를 통해 요청을 받고 Dto가 controller의 Request 데이터를 받아 변경 등의 처리를 한 후 Response

스터디 팀원분의 정리본을 통해 개념을 정리할 수 있었다.

JPA Auditing

Audit: 감시하다, 감사하다라는 뜻
Spring Data JPA에서 시간에 대해서 자동으로 값을 넣어주는 기능

  • 보통 엔티티에서는 해당 데이터의 생성 시간, 수정 시간 포함
  • 매번 DB에 삽입, 갱신하기 전에 날짜 데이터를 등록/수정하는 코드가 곳곳에 들어가게 됨 -> 번거로움
  • 도메인을 영속성 컨텍스트에 저장하거나 조회를 수행한 후에 update를 하는 경우 매번 시간 데이터를 입력하여 주어야 하는데, JPA Auditing을 사용하면 자동으로 시간을 매핑하여 데이터베이스의 테이블에 넣어주게 됨
profile
No Stress🎈 Be Happy✨

0개의 댓글