dew's CSE Studying
스프링부트3 백엔드 12~14장 본문
12장 서비스 계층과 트랜잭션
12.1 서비스와 트랜잭션의 개념
서비스(service): 컨트롤러와 리파지터리 사이에 위치하는 계층
-서버의 핵심 기능(비즈니스 로직)을 처리하는 순서를 총괄한다
트랜잭션(transaction): 모두 성공해야 하는 일련의 과정
롤백(rollback): 트랜잭션이 실패로 돌아갈 경우 진행 초기 단계로 돌리는 것
12.2 서비스 계층 만들기
@Autowired
private ArticleRepository articleRepository; //게시글 리파지터리 객체 주입
}
일단 게시글 리파지터리 객체를 주입해주었다
12.2.1. 게시글 조회 요청 개선하기
- 모든 게시글 조회 요청 개선하기
// GET
@GetMapping("/api/articles")
public List<Article> index() {
return articleService.index();
}
public List<Article> index() {
return articleRepository.findAll();
}
DB에서 조회한 결과를 반환한다
- 단일 게시글 조회 요청 개선하기
@GetMapping("/api/articles/{id}")
public Article show(@PathVariable Long id) {
return articleService.show(id);
}
@GetMapping("/api/articles/{id}")
public Article show(@PathVariable Long id) {
return articleService.show(id);
}
12.2.2 게시글 생성 요청 개선하기
이번엔 create 부분을 수정해보자
@PostMapping("/api/articles")
public ResponseEntity<Article> create(@RequestBody ArticleForm dto) {
Article created = articleService.create(dto);
return (created != null) ?
ResponseEntity.status(HttpStatus.OK).body(created) :
ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
public Article create(ArticleForm dto) {
Article article = dto.toEntity();
return articleRepository.save(article);
}
12.2.3 게시글 수정 요청 개선하기
update 부분 수정하기
@PatchMapping("/api/articles/{id}")
public ResponseEntity<Article> update(@PathVariable Long id,
@RequestBody ArticleForm dto) {
Article updated = articleService.update(id, dto);
return (updated != null) ?
ResponseEntity.status(HttpStatus.OK).body(updated) :
ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
public Article update(Long id, ArticleForm dto) {
// 1. DTO -> 엔터티 변환하기
Article article = articleRepository.findById(id).orElse(null);
log.info("id: {}, article: {}", id, article.toString());
// 2. 타깃 조회하기
Article target=articleRepository.findById(id).orElse(null);
// 3. 잘못된 요청 처리하기
if (target == null || id != article.getId()) {
// 400, 잘못된 요청 응답!
log.info("잘못된 요청! id: {}, article: {}", id, article.toString());
return null;
}
// 4. 업데이트 및 정상 응답(200)하기
target.patch(article);
Article updated= articleRepository.save(target);
return updated;
}
12.2.4 게시글 삭제 요청 개선하기
delete 수정하기
// DELETE
@DeleteMapping("/api/articles/{id}")
public ResponseEntity<Article> delete(@PathVariable Long id) {
Article deleted = articleService.delete(id);
return (deleted != null) ?
ResponseEntity.status(HttpStatus.OK).body() :
ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
public Article delete(Long id) {
// 1. 대상 찾기
Article target = articleRepository.findById(id).orElse(null);
// 2. 잘못된 요청 처리하기
if (target == null) {
return null;
}
// 3. 대상 삭제하기
articleRepository.delete(target);
return target;
}
12.3 트랜잭션 맛보기
- 게시판에 데이터 3개를 한꺼번에 생성 요청하기
- 데이터를 DB에 저장하는 과정에서 의도적으로 오류 발생시키기
- 어떻게 롤백되는지 확인하기
public List<Article> createArticles(List<ArticleForm> dtos) {
// 1. dto 묶음을 엔티티 묶음으로 변환하기
List<Article> articleList = dtos.stream()
.map(dto->dto.toEntity())
.collect(Collectors.toList());
// 2. 엔티티 묶음을 DB에 저장시키기
articleList.stream()
.forEach(article -> articleRepository.save(article));
// 3. 강제 예외 발생시키기
articleRepository.findById(-1L)
.orElseThrow(() -> new IllegalArgumentException("결제 실패!"));
// 4. 결과 값 반환하기
return articleList;
}
@Transactional
을 추가해주었다
13장 테스트 코드 작성하기
13.1 테스트란
테스트(test): 프로그램의 품질을 검증하는 것으로, 프로그램이 잘 동작하는지 확인하는 과정
테스트 코드의 3단계
- 예상 데이터 작성하기(=테스트 케이스 작성)
- 실제 데이터 획득하기
- 예상 데이터와 실제 데이터 비교해 검증하기
13.2 테스트 코드 작성하기
13.2.1 테스트 코드 기본 틀 만들기
13.2.2 index() 테스트하기
Arrays.asList() 메서드: 입력된 배열 또는 2개 이상의 동일한 타입 데이터를 정적 리스트로 만들어 반환한다
13.2.3 show() 테스트하기
13.2.4 create() 테스트하기
13.2.5 여러 테스트 케이스 한 번에 실행하기
데이터를 조회(read)하는 테스트를 제외하고 데이터를 생성, 수정, 삭제하는 테스트를 할 때는 반드시 해당 테스트르 ㄹ트랜잭션으로 묶어 테스트가 종료한 후 원래대로 돌아갈 수 있게 롤백 처리해주어야 한다!
Part 4 댓글 CRUD 만들기
14장 댓글 엔티티와 리파지터리 만들기
14.1 댓글 기능의 개요
14.1.1 댓글과 게시글의 관계
-일대다(1:n) 관계
-id같이 자신을 대표하는 속성인 대표키(pk) 존재
-article_id같이 연관 대상을 가리키는 속성인 외래키(fk) 존재
14.1.2 댓글 엔티티와 리파지터리 설계
- 엔터티: DB 데이터를 담는 자바 객체로, 엔티티를 기반으로 테이블 생성
- 리파지터리: 엔티티를 관리하는 인터페이스로, 데이터 CRUD 등의 기능 제공
각 인터세이스의 기능
- Repository: 최상위 리파지터리 인터페이스
- CrudRepository 및 ListCrudRepository: 엔티티의 CRUD 기능 제공
- PagingAndSortingRepository 및 ListPagingAndSortingRepository: 엔티티의 페이징 및 정렬 기능 제공
- JpaRepository: 엔티티의 CRUD 기능과 페이징 및 정렬 기능+JPA에 특화된 기능을 추가로 제공
14.2 댓글 엔티티 만들기
14.2.1 댓글 엔티티 만들기
14.2.2 더미 데이터 추가하기
14.2.3 댓글 조회 쿼리 연습하기
- 특정 게시글의 모든 댓글 조회
- 특정 닉네임의 모든 댓글 조회
14.3 댓글 리파지터리 만들기
14.3.1 댓글 리파지터리 만들기
네이티브 쿼리 메서드(native query method): 직접 작성한 SQL 쿼리를 리파지터리 메서드로 실행할 수 있게 해준다
방법: @Query / orm.xml 파일 이용
- 특정 게시글의 모든 댓글 조회_@Query
- 특정 닉네임의 모든 댓글 조회_orm.xml
14.3.2 댓글 리파지터리 테스트 코드 작성하기
- findAllByArticleId()
'3-1 > [inflearn]스프링입문' 카테고리의 다른 글
스프링부트3 백엔드 17장~19장 (1) | 2024.12.27 |
---|---|
스프링부트3 백엔드 15장-16장 (0) | 2024.12.21 |
스프링부트3 자바 백엔드 9장~11장 (0) | 2024.11.23 |
스프링부트3 백엔드 개발 6~8장 (4) | 2024.11.16 |
스프링부트3 백엔드 개발 3~5장 (1) | 2024.11.09 |