Develop/Java
게시판 상세페이지에서 이전글, 다음글 구현하기
롱하
2024. 7. 2. 16:42
게시판 상세페이지에서 이전글과 다음글을 구현하는 경우가 굉장히 많았는데 그걸 한번 정리해보고 싶어졌다.
- Controller
@Controller
@RequiredArgsConstructor
public class MediaViewController {
private final MediaViewService mediaSubViewService;
private final ModelMapper modelMapper;
private final MediaRepo mediaRepo;
@GetMapping("/media/{id}")
String operate(@PathVariable(required = true) Long id,
Model model, @ModelAttribute("paramDto") MediaConditionDto paramDto) {
paramDto.setSearchLang(LangType.ko.name());
paramDto.setSearchTargetId(id);
MediaEntity media = mediaRepo.findByLangAndId(paramDto.getSearchLang(), paramDto.getSearchTargetId());
MediaDto dto = modelMapper.map(mediaSubViewService.operate(modelMapper.map(paramDto, MediaCondition.class)), MediaDto.class);
model.addAttribute("dto", dto);
return "media/view";
}
}
이전글 다음글은 view에서 제목만 뜨지만 결국 해당 게시글의 상세페이지로 넘어가야하기 때문에 해당 게시글의 id와 전체 데이터를 가져와야한다.
그래서 MediaDto에
- Dto
private Media prevMedia;
private Media nextMedia;
이렇게 Media model을 그대로 이전글 다음글로 추가해주었다.
- Service
@Service
@RequiredArgsConstructor
public class MediaViewServiceImpl implements MediaViewService {
private final MediaViewDao mediaViewDao;
private final MediaViewPrevDao mediaViewPrevDao;
private final MediaViewNextDao mediaViewNextDao;
@Override
public Media operate(MediaCondition paramDto) {
Media media mediaViewDao.operate(paramDto);
if(media != null) {
media.setPrevMedia(mediaViewPrevDao.operate(media.getCreatedAt()));
media.setNextMedia(mediaViewNextDao.operate(media.getCreatedAt()));
}
return media;
}
}
그리고 기존의 ViewService에서 이전글 데이터와 다음글 데이터를 불러올 Dao를 각각 Import해와서 해당 게시글이 null값이 아닐 경우에는 각 이전글 다음글 데이터를 불러오는Dao를 실행시켜준다.
@Repository
@RequiredArgsConstructor
public class NoticeViewPrevDaoImpl implements NoticeViewPrevDao {
private final NoticeSubRepo noticeSubRepo;
private final ModelMapper modelMapper;
public NoticeSub operate(LocalDateTime createdAt, Long noticeId) {
List<NoticeSubEntity> notice = noticeSubRepo.findTop1ByOrderByCreatedAtAsc(createdAt, noticeId, PageRequest.of(0, 1));
return notice.size() > 0 ? modelMapper.map(notice.get(0), NoticeSub.class) : null;
}
}
@Repository
@RequiredArgsConstructor
public class NoticeViewNextDaoImpl implements NoticeViewNextDao {
private final NoticeSubRepo noticeSubRepo;
private final ModelMapper modelMapper;
public NoticeSub operate(LocalDateTime createdAt, Long noticeId) {
List<NoticeSubEntity> notice = noticeSubRepo.findTop1ByOrderByCreatedAtDesc(createdAt, noticeId, PageRequest.of(0, 1));
return notice.size() > 0 ? modelMapper.map(notice.get(0), NoticeSub.class) : null;
}
}
public interface NoticeSubRepo
extends JpaRepository<NoticeSubEntity, Long>, JpaSpecificationExecutor<NoticeSubEntity>{
NoticeSubEntity findByLangAndId(String lang, Long id);
@Query("select t from NoticeSubEntity t where t.dispYn = 'Y' and t.notice.id = :noticeId and t.createdAt > :createdAt order by t.createdAt asc")
List<NoticeSubEntity> findTop1ByOrderByCreatedAtAsc(LocalDateTime createdAt, Long noticeId, Pageable pageable);
@Query("select t from NoticeSubEntity t where t.dispYn = 'Y' and t.notice.id = :noticeId and t.createdAt < :createdAt order by t.createdAt desc")
List<NoticeSubEntity> findTop1ByOrderByCreatedAtDesc(LocalDateTime createdAt, Long noticeId, Pageable pageable);
void deleteByIdIn(List<Long> itemIds);
}