스프링 부트와 AWS로 혼자 구현하는 웹 서비스(2)

김나우·2022년 3월 30일
0

이 포스팅은 스프링 부트와 AWS로 혼자 구현하는 웹 서비스
를 보며 공부한 내용을 정리하는 포스팅입니다.

JPA를 사용해 게시판 만들어 보기

Spring Data JPA를 적용하기 위해 build.gradle에 설정을 해준다

후에 domain패키지를 만들어 준다
도메인이란 게시글, 댓글, 회원, 정산, 결제 등 소프트웨어에 대한 요구사항 혹은 문제 영역
이라고 생각하면 된다

도메인 밑에 posts디렉토리와 posts 클래스를 만들어 준다

여기서 Posts 클래스는 실제 DB의 테이블과 매칭될 클래스이며 Entity 클래스라고도 한다.
JPA를 사용하면 DB 데이터에 작업할 경우 실제 쿼리를 날리기보다는, Entity 클래스의
수정을 통해 작업한다

@Entity
-> 테이블과 링크될 클래스임을 나타냄
-> 기본값으로 클래스의 카멜케이스 이름을 언더스코어 네이밍으로 테이블 이름을 매칭
ex) SalesManager.java -> sales_manager table

@Id
-> 해당 테이블의 PK 필드를 나타냄

@GeneratedValue
-> PK의 생성 규칙을 나타냄
-> 스프링 부트 2.0에서는 GenerationType.IDENTITY 옵션을 추가해야만 auto_increment가 됨.

@Column
-> 테이블의 칼럼을 나타내며 굳이 선언하지 않아도 됨
-> 사용하는 이유는, 기본값 외에 추가로 변경이 필요한 옵션이 있으면 사용
-> 문자열의 경우 VARCHAR(255)가 기본값인데, 사이즈를 500으로 늘리고 싶거나, 타입을 TEXT로 변경하고 싶거나 하는 경우에 사용

@NoArgsConstructor
-> 기본 생성자 자동 추가
-> public Posts(){}와 같은 효과

@Getter
-> 클래스 내 모든 필드의 Getter 메소드를 자동 생성

@Builder
-> 해당 클래스의 빌더 패턴 클래스를 생성
-> 생성자 상단에 선언 시 생성자에 포함된 빌드만 빌더에 포함

이 Posts 클래스에는 한 가지 특이점이 있다. 그건 바로 Setter 메소드가 없다는 점이다
자바빈 규약을 생각하면서 getter/setter를 무작정 생성하는 경우가 있다
Entity 클래스에서는 절대 setter 메소드를 만들지 않고, 대신 해당 필드의 값 변경이 필요한 경우
명확히 그 목적과 의도를 나타낼 수 있는 메소드를 추가해야 한다.

그럼 위 코드에서는 Setter가 없는데 어떻게 값을 채워 DB에 삽입할까?

기본적인 구조는 생성자를 통해 최종값을 채운 후 DB에 삽입하며, 값 변경이 필요한 경우
해당 이벤트에 맞는 public 메소드를 호출하여 변경하는 것을 전제로 한다.

이 책에서는 생성자 대신에 @Builder를 통해 제공되는 빌더 클래스를 사용했다
생성자나 빌더나 생성 시점에 값을 채워주는 역할은 똑같다.

후에 Posts 클래스로 Database를 접근하게 해줄 JpaRepository를 생성한다
(인터페이스다)

인터페이스를 생성 후 JpaRepository<Entity 클래스, PK 타입>를 상속하면 기본적인
CRUD 메소드가 자동으로 생성된다
@Repository를 추가할 필요도 없다 주의할 점은 Entity 클래스와 기본 Entity Repository는 함께 위치해야 한다.

이제 PostsRepository 테스트 클래스를 만들어준다

새로보는 애노테이션들이 생겼다

@After
-> Junit에서 단위 테스트가 끝날 때마다 수행되는 메소드를 지정
-> 보통은 배포 전 전체 테스트를 수행할 때 테스트간 데이터 침범을 막기 위해 사용
-> 여러 테스트가 동시에 수행되면 테스트용 데이터베이스인 H2에 데이터가 그대로 남아 있어 다음 테스트 실행 시 실패할 수도 있음

postsRepository.save
-> 테이블 posts에 insert/update 쿼리를 실행
-> id 값이 있다면 update, 없다면 insert 실행

postsRepository.findAll()
-> 테이블 posts에 있는 모든 데이터를 조회해오는 메소드


등록/수정/조회 API 만들기

API를 만들기 위해 총 3개의 클래스가 필요하다

  • Request 데이터를 받을 Dto
  • API 요청을 받을 Controller
  • 트랜잭션, 도메인 기능 간의 순서를 보장하는 Service

    Service는 트랜잭션, 도메인 간 순서 보장의 역할을 한다.

Spring 웹 계층

Web Layer
-> 흔히 사용하는 @Controller와 JSP/Freemarker 등의 뷰 템플릿 영역이다
-> 필터(@Filter), 인터셉터, 컨트롤러 어드바이스(@ControllerAdvice)등 외부 요청과 응답에 대한 전반적인 영역을 이야기 한다.

ServiceLayer
-> @Service에 사용되는 서비스 영역이다.
-> 일반적으로 Controller와 Dao의 중간 영역에서 사용된다
-> @Transactional이 사용되어야 하는 영역이다

Repository Layer
-> Database와 같이 데이터 저장소에 접근하는 영역

Dtos
-> Dto(Data Transfer Obejct)는 계층 간에 데이터 교환을 위한 객체를 이야기 하며
Dtos는 이들의 영역을 얘기함.

Domain Model
-> 도메인이라 불리는 개발 대상을 모든 사람이 동일한 관점에서 이해할 수 있고 공유할 수 있도록 단순화시킨 것을 도메인 모델이라고 함.
-> @Enitiy가 사용된 영역 역시 도메인 모델이다.

WEb, Service, Repository, Dto, Domain 이 5가지 레이어에서 비지니스 처리를 담당하는 곳은
Domain 이다.

PostsApiController와 PostsService, PostsSaveRequestDto를 생성해 준다.


여기서 보면 Entity 클래스와 거의 유사한 형태임에도 Dto 클래스를 추가로 생성했다.
하지만, 절대로 Entity 클래스를 Request/Response 클래스로 사용해서는 안 된다.
Entity 클래스는 데이터베이스와 맞닿은 핵심 클래스이기 때문이다


수정/조회 기능 추가

컨트롤러에 Update와 findById를 추가해줬다

PostsRequestDto를 만들었다.

PostsUpdateRequestDto를 만들었다.

Posts에 update를 추가해줬다.

PostsService에 update와 findById를 추가해줬다

신기한게 update기능에서 데이터베이스에 쿼리를 날리는 부분이 없다
이게 가능한 이유는 JPA의 영속성 컨텍스트 덕분이다

영속성 컨텍스트란, 엔티티를 영구 저장하는 환경이다

JPA Auditing으로 생성시간/수동시간 자동화하기

보통 엔티티에는 해당 데이터의 생성시간과 수정시간을 포함한다
언제 만들어졌는지, 언제 수정되었는지 등 차후 유지보수에 있어서 매우 중요한 정보이기 때문이다.

BaseTimeEntity라는 추상 클래스를 만들어 줬다.
BaseTimeEntity클래스는 모든 Entity의 상위 클래스가 되어 Entity들의
createdDate, modifiedDate를 자동으로 관리하는 역할이다.

@MappedSuperclass
-> JPA Entity 클래스들이 BaseTImeEntity를 상속할 경우 필드들(created~,modi~)
도 칼럼으로 인식하도록 한다.

@EntityListeners(AuditingEntityListener.class)
-> BaseTimeEntity 클래스에 Auditing 기능을 포함시킨다.

@CreatedDate
-> Entity가 생성되어 저장될 때 시간이 자동 저장된다.

@LastModifiedDate
-> 조회한 Entity의 값을 변경할 때 시간이 자동 저장된다.

그리고 Posts 클래스가 BaseTimeEntity를 상속받도록 변경한다.

요렇게

그리고 JPA Auditing 어노테이션들을 모두 활성화할 수 있도록 Application 클래스에
활성화 어노테이션 하나를 추가한다

근데 궁금하다 Jpa Auditing가 뭘까

Jpa Auditing
Audit은 감시하다,감사하다 라는 뜻으로 Spring Data JPA에서 시간에 대해서 자동으로 값을 넣어 주는 기능이다. 도메인을 영속성 컨텍스트에 저장하거나 조회를 수행한 후에 update를 하는 경우 매번 시간 데이터를 입력해 주어야 하는데, audit을 이용하면 자동으로 시간을 매핑하여 데이터베이스의 테이블에 넣어준다.
출처 : https://webcoding-start.tistory.com/53

profile
안녕하세요

0개의 댓글

관련 채용 정보