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);
	
}