롯데ON의 커뮤니티 목록 페이지는 공지사항, 자유게시판, 자료실 세 가지 카테고리로 구성되어 있으며, 각 카테고리별로 게시글을 분리해서 조회할 수 있습니다.
QueryDSL 기반의 동적 쿼리를 활용해 카테고리 조건을 유연하게 처리했으며, 페이징 처리를 통해 대량 데이터도 빠르게 로드할 수 있도록 구현했습니다.
Community1Controller
/notice, /free, /resource)으로 진입 시, PageRequestDTO를 받아 카테고리 값을 세팅하고, 해당 조건으로 조회 요청을 보냅니다.PageResponseDTO로 받아 Model에 등록하여 View에 전달합니다.@GetMapping("/Community/notice")
public String notice(PageRequestDTO pageRequestDTO, Model model) {
pageRequestDTO.setCate("notice");
PageResponseDTO pageResponseDTO = communityService.findAll(pageRequestDTO);
model.addAttribute(pageResponseDTO);
return "/Community/notice";
}
Community1Service
PageRequestDTO에서 getPageable("no")로 정렬 조건을 포함한 페이지 정보를 생성합니다.communityRepository1.selectAllForList()를 통해 카테고리 + 검색조건 기반 게시글 목록을 Tuple로 조회합니다.Tuple 결과에서 게시글 엔티티와 작성자 이름을 추출하고, ModelMapper로 DTO 변환을 수행하여 PageResponseDTO로 반환합니다.Page<Tuple> pageCommunity = communityRepository1.selectAllForList(pageRequestDTO, pageable);
List<Community1DTO> communityDTOList = pageCommunity.getContent().stream().map(tuple -> {
Community1 community = tuple.get(0, Community1.class);
String name = tuple.get(1, String.class);
Community1DTO dto = modelMapper.map(community, Community1DTO.class);
dto.setName(name);
return dto;
}).toList();
Community1RepositoryImpl
QueryDSL을 활용해 cate 조건을 기반으로 동적 where절을 구성합니다.Community1 엔티티와 User.name을 조인하여 Tuple로 반환합니다.offset, limit, orderBy를 지정하고, count() 쿼리를 별도로 수행해 전체 게시글 수를 구합니다. @Override
public Page<Tuple> selectAllForList(PageRequestDTO pageRequestDTO, Pageable pageable) {
String cate = pageRequestDTO.getCate();
BooleanExpression expression = qCommunity.cate.contains(cate);
List<Tuple> tupleList = queryFactory
.select(qCommunity, qUser.name)
.from(qCommunity)
.join(qUser)
.on(qCommunity.user.id.eq(qUser.id))
.where(expression)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(qCommunity.no.desc())
.fetch();
long total = queryFactory
.select(qCommunity.count())
.from(qCommunity)
.join(qUser)
.on(qCommunity.user.id.eq(qUser.id))
.where(expression)
.fetchOne();
return new PageImpl<>(tupleList, pageable, total);
}
PageRequestDTO: 클라이언트 요청값을 담는 객체로, cate, pg, size, searchType, keyword 등을 포함합니다. getPageable() 메서드로 PageRequest를 생성합니다.PageResponseDTO: dtoList, total, pg, start, end, prev, next 등의 페이징 정보를 계산해서 전달합니다.@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResponseDTO<T> {
private List<T> dtoList;
private String cate;
private int pg;
private int size;
private int total;
private int startNo;
private int start, end;
private boolean prev, next;
private String searchType;
private String keyword;
}