프로젝트에 참고한 책: '스프링 부트와 AWS로 혼자 구현하는 웹 서비스'

엔티티의 생성 및 수정 시간을 손쉽게 입력하기 위해 JPA Auditing을 사용한다. 

BaseEntity abstract class를 domain 패키지에 생성한다. 

코드는 다음을 참고하면된다. 

 

  • @MappedSuperclass: JPA Entity 클래스들이 BaseTimeEntity를 상속할 경우 필드들도 칼럼으로 인식하도록 해준다.
  • @EntityListeners(AuditingEntityListener.class): BaseTimeEntity 클래스에 Auditing 기능을 포함시킨다

 

원래는 Application에 @EnableJpaAuditing을 추가하면 되지만 추후에 로그인 관련 해서 설정할 때 이거 때문에 오류가 발생할 수 있으므로  /config 패키지에 JPAConfig 클래스를 생성해 다음과 같이 코드를 작성하면 된다. 

프로젝트에 참고한 책: '스프링 부트와 AWS로 혼자 구현하는 웹 서비스'

수정기능을 입력하는 순서는 다음과 같다

1. PostsApiController에 update() 와 findById() 메소드 생성

-update() 메소드

  • Long Type
  • @PutMapping()
  • @PathVariable
  • @RequestBody

- findById() 

  • PostsResponseDto
  • @GetMapping()
  • @PathVariable

 

2. PostsReponseDto 생성( GitHub 위치: /web/dto)

해당 Dto는 Entity의 필드 중 일부만 사용하므로 생성자로 Entity를 받아 필드 값에 넣고 response한다. 

 

 

3. PostsUpdateRequestDto 생성( GitHub 위치: /web/dto)

 

 

4. Posts에 update 생성자 생성

 

5. PostsService에 update(), findById() 메소드 생성 

 

  • update()

 

  • findById()

 

6. PostsApiControllerTest 실행 

 

게시글_저장 test와 다른 점은 세가지가 있어서 짚어보려한다. 

 

첫번째, 수정은 기존에 저장되어있는 정보를 바꾸는 일이므로 처음 정보를 저장하고, 바꿀 정보도 입력해야해서 두개의 객체              를 생성해야한다. 

두번째, requestEntity를 생성해야한다. 

세번째, //when 부분에서 restTemplate.exchange()를 이용하고, HttpMethod.PUT을 파라미터로 넣는다. 

 

 

자세한 코드는 다음 페이지에서 확인할 수 있다. 

https://github.com/heyazoo1007/bookproject/blob/master/src/test/java/com/heyazoo1007/book/web/PostsApiControllerTest.java

프로젝트에 참고한 책: '스프링 부트와 AWS로 혼자 구현하는 웹 서비스'

1. API를 만들기 위한 3개의 클래스들

API를 만들기 위한 3개의 클래스는 다음과 같다 

 

-Request 데이터를 받을 Dto

-API 요청을 받을 Controller

-트랜잭션,도메인 기능 간의 순서를 보장하는 Service

 

Spring web Layer의 구성요소: Web Layer, Service Layer, Repository Layer, Dtos, Domain Model

실제로 비즈니스 로직을 처리하는 곳은 Service 클래스가 아니라 Domain이다. 

 

2. 등록/수정/조회 기능 만들기 

먼저 web package를 만들고 controller와 dto를 생성한다. 

 

web package PostsApiController.class
web.dto package PostsSaveRequestDto.class

 

PostsApiController: 해당 api를 통해 requestDto를 받아 service 클래스로 넘긴다.

PostsSaveRequestDto

: 클라이언트에서 request한 정보를 포함하고 있다. 

 

Entity 클래스를 response/request 클래스로 사용하면 안되고, 반드시 dto를 따로 생성해야한다. 

이유는 다음과 같다.

 

-Entity 클래스는 데이터베이스와 맞닿은 핵심 클래스(이걸 기준으로 테이블이 생성되고, 스키마가 변경됨)이기 때문에 

쉽게 변경하면 안된다. 

-그런데 response/request 클래스는 view와 맞닿은 클래스이므로 수시로 변경될 가능성이 있기 때문에 만약 entity가 dto로 사용된다면 잘못될 가능성이 높다. 

 

따라서 reponse/request dto는 entity class와는 별도로 따로 생성하자. 

 

 

자세한 코드는 다음 주소에서 확인하면 된다. 

https://github.com/heyazoo1007/bookproject/tree/master/src/main/java/com/heyazoo1007/book/web

 

 

두번째로 service.posts package를 만들고 service class를 생성한다

 

services.posts package PostsService.class

 

자세한 코드는 다음 주소에서 확인할 수 있다. 

https://github.com/heyazoo1007/bookproject/blob/master/src/main/java/com/heyazoo1007/book/service/posts/PostsService.java

 

 

3. 스프링에서 Bean을 주입하는 방법 3가지

- @Autowired

- setter

- 생성자(constructor) 

 

책에서는 @Autowired 로 주입하는 것보다, 생성자로 주입하는 것을 더 추천한다.

 

생성자로 Bean 객체를 받도록 하면 @Autowired와 동일한 효과를 볼 수 있다. 

final이 선언된 모든 필드를 인자값으로 하는 생성자를 @RequiredArgsConstructor가 생성해준다. 

 

생성자를 직접 안 쓰고 @RequiredArgsConstructor(롬복 어노테이션)을 사용한 이유

: 해당 클래스의 의존성 관계가 변경될 때마다 생성자 코드를 계속해서 수정하는 번거로움을 해결하기 위함이다. 

 

 

4. PostsApiControllerTest

 

코드는 다음 주소로 가면 확인할 수 있다. 

https://github.com/heyazoo1007/bookproject/tree/master/src/test/java/com/heyazoo1007/book/web

 

Test 관련 공부한 내용

 

//given part 

-ControllerTest에서는 따로 url을 설정해서 테스트를 수행해야한다.

그러기 위해서는 임의의 port 번호를

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)

@LocalServerPort \ private int port; 를 이용해서 생성한다. 

 

//when part 

-TestRestTemplate 사용 

//when 파트를 보면 responseEntity= restTemplate.postForEntity();를 생성한다. 

 

자세한 내용은 다음 페이지를 참고하면 된다. 

https://heyazoo1007.tistory.com/212

//then part

-assertThat(responseEntity.getStatusCode()).isEqualTo(HttpsStatus.OK);

-assertThat(responseEntity.getBody()).isGreaterThan(0L);

 

상태가 200인지 확인하고, Body의 길이가 0 이상인지 확인 한다. 

 

 

프로젝트에 참고한 책: '스프링 부트와 AWS로 혼자 구현하는 웹 서비스'

1. build.gradle에 dependencies 추가하기

 

2. domain 패키지 만들기 

 

도메인: 게시글,댓글,회원,정산,결제 등 소프트웨어에 대한 요구사항 혹은 문제영역이라고 보면 된다.

본 프로젝트에서는 도메인이 게시글이므로, Posts 클래스와 PostsRepository 인터페이스를 생성했다.

Entity class와 Repository Interface는 밀접한 관계이므로 같은 domain package에 있어야한다. 

 

3.Posts Class

Posts클래스는 실제 DB의 테이블과 매칭될 클래스이므로 @Entity(JPA 어노테이션, 테이블과 링크될 클래스임을 나타내는 어노테이션)가 클래스 명과 가장 가까워야 한다. 

나머지는 롬복 어노테이션이다. 

 

코드 상세는 다음 주소로 들어가면 볼 수 있다. 

https://github.com/heyazoo1007/bookproject/blob/master/src/main/java/com/heyazoo1007/book/domain/posts/Posts.java

 

4.PostsRepository Interface 

ibatis,Mybatis에서 DB Layer 접근자는 Dao라고 부르고, JPA에서는 Repository라고 부르며 인터페이스로 생성한다. 

JpaRepository<Entity class, Pk type>를 상속하면 기본적인 CRUD 메소드가 자동으로 생성된다. 

 

 

Post와 PostsRepository 코드는 다음 깃헙에 가면 볼 수 있다.

https://github.com/heyazoo1007/bookproject/tree/master/src/main/java/com/heyazoo1007/book/domain/posts/PostsRepository.java

 

5. PostsRepositoryTest 

오류를 줄이기 위해서는 기능 구현을 완성하면 해당 단위 기능을 테스트 하는 테스트 코드를 작성해서 정상 작동하는지 확인하는 버릇을 들여야한다. TDD도 추후에 공부 해야한다.

 

테스트 코드는 다음 페이지로 가면 볼 수 있다.(게시글저장_불러오기 test)

https://github.com/heyazoo1007/bookproject/blob/master/src/test/java/domain/posts/PostsRepositoryTest.java

 

 

+ Recent posts