Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 코드로배우는스프링부트웹프로젝트
- 처음 만나는 AI수학 with Python
- Kernighan의 C언어 프로그래밍
- ㅒ
- iterator
- GIT
- 네트워크 설정
- 처음 만나는 AI 수학 with Python
- 코드로배우는스프링웹프로젝트
- network configuration
- 서버설정
- 구멍가게코딩단
- /etc/network/interfaces
- 자료구조와 함께 배우는 알고리즘 입문
- 친절한SQL튜닝
- d
- 리눅스
- 목록처리
- baeldung
- 알파회계
- 선형대수
- 스프링 시큐리티
- resttemplate
- 자료구조와함께배우는알고리즘입문
- 자바편
- 데비안
- 페이징
- 스프링부트핵심가이드
- 이터레이터
- 티스토리 쿠키 삭제
Archives
- Today
- Total
bright jazz music
guestbook : 06. 목록처리(1) 목록 가져오기 본문
● 목록처리 시 고려할 점
- 화면에서 필요한 목록 데이터에 대한 DTO 생성
- DTO를 Pageable 타입으로 전환
- Page<Entity>를 화면에서 사용하기 쉬운 DTO의 리스트 등으로 전환
- 화면에 필요한 페이지 번호 처리
목록 처리를 위한 DTO 생성하는 경우 아래의 사항을 고려해야 한다.
- 목록처리는 거의 모든 게시판 기능에서 사용
- 따라서 재사용 가능한 구조를 생성하는 것 권장
객체지향 언어인 자바에서는 클래스를 만들어서 사용하면 용이하다.
1. 페이지 요청을 처리하는 DTO 생성 (PageRequestDTO)
- PageRequestDTO는 목록 페이지를 요청할 때 사용
- 페이지 번호, 목록의 개수, 검색 조건 등이 포함되는 경향 존재
- 이러한 파라미터들을 DTO로 선언하고 추후 재사용
PageRequestDTO로 요청을 받고 결과는 PageResultDTo라는 클래스를 생성해 사용할 예정
//PageRequestDTO.java
package com.example.guestbook.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; //페이지 관련 임포트
import org.springframework.data.domain.Sort;
@Builder
@AllArgsConstructor
@Data
public class PageRequestDTO {
private int page;
private int size;
public PageRequestDTO(){
this.page = 1;
this.size = 10;
}
// 이 DTO의 목적은 JPA에서 사용하는 Pageable 타입의 객체를 생성하는 것이다.
// JPA를 이용하는 경우에는 페이지 번호가 0부터 시작한다.
// 따라서 1페이지의 경우 0이 될 수 있도록 아래와 같이 작성한다.
// 정렬(Sort)는 다양한 상황에서 사용하기 위해서 별도의 파라미터로 받도록 설계.
public Pageable getPageable(Sort sort) {
return PageRequest.of(page - 1, size, sort );
}
}
2. 페이지 결과처리를 위한 DTO 생성 (PageResultDTO)
- JPA를 이용하는 Repository에서는 페이지 결과를 Page<Entity> 타입으로 반환.
- 따라서 서비스 계층에서 이를 사용하려면 별도의 클래스를 만들어 처리해야 함.(여기서는 PageResultDTO)
- PageResultDTO는 Page<Entity>의 객체들을 DTO로 변환해서 자료구조로 담아줘야 한다.
- PageResultDTO는 화면 출력에 필요한 정보를 구성해 주어야 한다.
//PageResultDTO.java
package com.example.guestbook.dto;
import lombok.Data;
import org.springframework.data.domain.Page;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
@Data
public class PageResultDTO<DTO, EN> {
// 다양한 곳에서 사용할 수 있도록 제네릭 타입을 이용해서 DTO와 EN 타입을 지정. (EN = Entity)
private List<DTO> dtoList;
//PageResultDTO는 Page<Entity> 타입을 이용해서 생성할 수 있도록 생성자로 작성.
public PageResultDTO(Page<EN> result, Function<EN, DTO> fn){
//Function: 엔티티 객체들을 DTO로 변환해 주는 기능
dtoList = result.stream().map(fn).collect(Collectors.toList());
}
// 이와 같은 제네릭 방식을 적용하면 추후 추가적인 클래스를 작성하지 않고도 목록 데이터를 처리할 수 있다.
/*
* PageResultDTO는 List<DTO> 타입으로 DTO 객체들을 보관한다.
* 그렇기 때문에 Page<Entity>의 내용물 중에서 엔티티 객체를 DTO로 변환하는 기능이 필요하다.
* 가장 일반적인 형태는 추상 클래스를 이용해서 이를 처리하는 방식이다.
* 그러한 경우 매번 새로운 클래스가 필요하다는 단점이 있다.
*
* 이번 프로젝트의 경우 엔티티 객체의 DTO 변환은 서비스 인터페이스에 정의한
* entityToDto() 메서드와 별도로 Function객체로 만들어서 처리한다.
* */
}
3. 서비스 계층에서의 목록처리
- 서비스 계층에서는 PageRequestDTO를 파라미터로, PageResultDTO를 리턴타입으로 사용하는 getList() 메서드를 설계한다.
- 또한 엔티티 객체를 DTO 객체로 변환하는 entityToDto()를 정의한다.
//GuestbookService.java (인터페이스)
package com.example.guestbook.service;
import com.example.guestbook.dto.GuestbookDTO;
import com.example.guestbook.dto.PageRequestDTO;
import com.example.guestbook.dto.PageResultDTO;
import com.example.guestbook.entity.Guestbook;
import org.springframework.stereotype.Service;
//@Service 어노테이션은 GuestbookImple에 적어준다.
public interface GuestbookService { //GuestbookImple 클래스에서 이 인터페이스를 상속한다.
Long register(GuestbookDTO dto); // GuestbookImple 클래스에서 오버라이딩
//getList()메서드
PageResultDTO<GuestbookDTO, Guestbook> getList(PageRequestDTO requestDTO);
//dto에서 Entity로의 변환작업
default Guestbook dtoToEntity(GuestbookDTO dto) {
Guestbook entity = Guestbook.builder()
.gno(dto.getGno())
.title(dto.getTitle())
.content(dto.getContent())
.writer(dto.getWriter())
.build();
return entity;
}
//Entity에서 DTO로의 변환작업
default GuestbookDTO entityToDto(Guestbook entity) {
GuestbookDTO dto = GuestbookDTO.builder()
.gno(entity.getGno())
.title(entity.getTitle())
.content(entity.getContent())
.writer(entity.getWriter())
.build();
return dto;
}
}
/*
* default 메서드:
* 인터페이스의 실제 내용을 가지는 코드를 default라는 키워드로 생성 가능.
* default 메서드를 이용하면 기존에 추상 클래스를 통해 전달해야 하는 실제 코드를
* 인터페이스에 선언할 수 있음.
*
* '인터페이스 -> 추상클래스 -> 구현 클래스'의 형태에서 추상클래스를 생략하는 것이 가능해짐.
* */
//GuestbookImpl.java
package com.example.guestbook.service;
import com.example.guestbook.dto.GuestbookDTO;
import com.example.guestbook.dto.PageRequestDTO;
import com.example.guestbook.dto.PageResultDTO;
import com.example.guestbook.entity.Guestbook;
import com.example.guestbook.repository.GuestbookRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import java.util.function.Function;
@Service //스프링이 빈으로 처리하도록 @Service 어노테이션 추가
@Log4j2
@RequiredArgsConstructor // <== 의존성 자동 주입!
public class GuestbookServiceImpl implements GuestbookService {
private final GuestbookRepository repository; //jpa 처리를 위해 repository 주입! 반드시 fianl 사용
@Override //GuestbookService에서 상속한 메서드 오버라이딩
public Long register(GuestbookDTO dto) {
log.info("DTO--------------------------------------");
log.info(dto);
Guestbook entity = dtoToEntity(dto); // GuestbookService에서 default를 이용하여 생성한 메서드
log.info(entity);
repository.save(entity); // 처리 저장.
// return null;
return entity.getGno(); //처리 후에는 엔티티의 gno 리턴
}
@Override
public PageResultDTO<GuestbookDTO, Guestbook> getList(PageRequestDTO requestedDTO){
Pageable pageable = requestedDTO.getPageable(Sort.by("gno").descending());
Page<Guestbook> result = repository.findAll(pageable);
Function<Guestbook, GuestbookDTO> fn = (entity -> entityToDto(entity));
return new PageResultDTO<>(result, fn);
}
}
getList() 메서드에서는 entityToDTO()를 이용해서 java.util.Function을 생성하고 이를 PageResultDTO로 구성한다.
PageResultDTO에는 JPA 처리 결과인 Page<Entity>와 Function을 전달해서 엔티티 객체들을 DTO의 리스트로 변환하고 화면에 페이지 처리와 필요한 값들을 생성한다.
4.테스트
//GuestbookServiceTests.java
package com.example.guestbook.service;
import com.example.guestbook.dto.GuestbookDTO;
import com.example.guestbook.dto.PageRequestDTO;
import com.example.guestbook.dto.PageResultDTO;
import com.example.guestbook.entity.Guestbook;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class GuestbookServiceTests {
@Autowired
private GuestbookService service;
@Test
public void testRegister(){
//테스트 객체 생성
GuestbookDTO guestbookDTO = GuestbookDTO.builder()
.title("Sample title...")
.content("Sample Content...")
.writer("user0")
.build();
//service.register() 테스트: 테스트 객체 사용
System.out.println(service.register(guestbookDTO));
}
@Test
public void testList(){ //목록처리 테스트
PageRequestDTO pageRequestDTO = PageRequestDTO.builder()
.page(1)
.size(10)
.build();
PageResultDTO<GuestbookDTO, Guestbook> resultDTO = service.getList(pageRequestDTO);
for(GuestbookDTO guestbookDTO : resultDTO.getDtoList()) {
System.out.println(guestbookDTO);
}
}
}
'Framework > Spring' 카테고리의 다른 글
guestbook : 06. 목록처리(3) 컨트롤러와 화면에서의 목록처리 (0) | 2022.07.08 |
---|---|
guestbook : 06. 목록처리(2) 데이터 페이지 처리 (0) | 2022.07.06 |
guestbook : 05. DTO를 사용한 Querydsl 테스트 (0) | 2022.07.01 |
guestbook : 04. querydsl 테스트 (0) | 2022.07.01 |
guestbook : 03. 자동 일자/시간 처리(등록/수정 등) +Querydsl (2) (0) | 2022.06.30 |
Comments