[점프 투 스프링부트] 답변에 페이징이 쉽지가 않습니다.
1번 방법. AnswerList와 Repository를 사용하는 방법
실패 사유 : Answer 엔티티에서 Question 엔티티를 참조한 속성명이므로 QuestionRepository에서 사용 불가
2번 방법. Answer 엔티티에서 Page 기능 삽입
실패 사유 : Question id와 연계하여 페이징을 해야 하는데 방법을 모르겠습니다.
(연계가 안되어 있어서 모든 ANSWER 엔티티가 나옵니다.)
여기서 어떤 점을 개선해야 될까요.....
[AnswerRepository]
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AnswerRepository extends JpaRepository<Answer, Integer> {
Page<Answer> findAll(Pageable pageable);
}
[AnswerService]
@RequiredArgsConstructor
@Service
public class AnswerService {
private final AnswerRepository answerRepository;
public Page<Answer> getList(int page) {
List<Sort.Order> sorts = new ArrayList<>();
sorts.add(Sort.Order.desc("Voter"));
sorts.add(Sort.Order.desc("createDate"));
Pageable pageable = PageRequest.of(page, 3, Sort.by(sorts));
return this.answerRepository.findAll(pageable);
}
[QuestionController]
@RequestMapping("/question")
@RequiredArgsConstructor
@Controller
public class QuestionController {
private final QuestionService questionService;
private final AnswerService answerService; //답변 페이징 기능을 위해 추가
private final UserService userService;
@RequestMapping(value = "/detail/{id}")
public String detail(Model model, @PathVariable("id") Integer id, AnswerForm answerForm, @RequestParam(value="page", defaultValue="0") int page) {
Question question = this.questionService.getQuestion(id);
Page<Answer> paging = this.answerService.getList(page);
model.addAttribute("paging", paging);
model.addAttribute("question", question);
return "question_detail";
}
ElectricComputer 님 882
2022년 7월 12일 12:09 오전
2개의 답변이 있습니다. 1 / 1 Page
AnswerRepository에는 다음을 추가하고
Page<Answer> findAll(Question question, Pageable pageable);
AnswerService는 다음처럼 수정해 보세요.
public Page<Answer> getList(Question question, int page) {
List<Sort.Order> sorts = new ArrayList<>();
sorts.add(Sort.Order.desc("Voter"));
sorts.add(Sort.Order.desc("createDate"));
Pageable pageable = PageRequest.of(page, 3, Sort.by(sorts));
return this.answerRepository.findAll(question, pageable);
}
그리고 상세화면 컨트롤러에서 답변 페이징 조회시 Question 객체를 추가로 전달해 보세요.
수정: findAll 이 아니고 findAllByQuestion으로 고쳐주세요.
박응용 님
M 2022년 7월 12일 10:52 오전
추천순으로 소트하려면 복잡하기 때문에 직접 쿼리를 작성하는것을 추천합니다.
AnswerRepository에 findAllByQuestion 메서드를 다음과 비슷하게 작성하시면 될것 같아요.
@Query(value="select "
+ "distinct a.*, count(av.answer_id) as voter_count "
+ "from answer a "
+ "left outer join answer_voter av on av.answer_id=a.id "
+ "where a.question_id = :questionId "
+ "group by a.id, av.answer_id "
+ "order by voter_count desc, a.create_date desc "
, countQuery = "select count(*) from answer"
, nativeQuery = true)
Page<Answer> findAllByQuestion(@Param("questionId") Integer questionId, Pageable pageable);
그리고 서비스에서 questionId를 전달하여 호출하면 됩니다. 그리고 Sort는 쿼리에서 했으니까 서비스에서 pageable에 등록한 Order by 항목들은 제거해야 합니다.
박응용 님
M 2022년 7월 13일 3:59 오후