본문 바로가기
혼자서 개발새발

Pageable 로 게시판 페이징을 해야 하는데 특정 컬럼이 존재한다면 안 보여주고 싶다

by 휴일이 2023. 5. 5.

 

 

게시판에서 리스트를 보여주는 것 까진 완성했다

내 게시판에서는 게시글을 삭제했을 때, delete 쿼리를 실행하는 것이 아닌

삭제 관련한 데이터를 추가시키고 게시판에 업데이트로 추가함으로서

삭제 관련 컬럼이 null 이 아닐 경우, 삭제 된 게시글임을 알 수 있다

그래서 단순히 findAll 해온다면 리스트에는 삭제 된 게시글이 보일 수밖에 없다

 

 

여기서 의문이 생겼는데

나는 삭제 컬럼이 null 일 경우에만 데이터를 보여줘야 한다

근데 null 체크 작업을

1. 서버에서 할 것인가

2. DB 에서 쿼리로 할 것인가

어떤 방법이 성능이 더 좋은지 의문이 들었다

이왕이면 성능이 좋게 작업하는 것이 좋잖아?

 

여기저기 물어봤는데 의견이 갈렸는데

스터디에서 어떤 분이 보내주신 컬럼이 도움되었다

https://www.itworld.co.kr/news/208352

 

비즈니스 로직을 DB가 아닌 앱에 넣어야 하는 이유

SQL 데이터베이스에서 데이터를 꺼내야 하는데, 이 데이터를 꺼내기 위해 여러 테이블 조인과 여러 필터 조건, 세밀한 WHERE 절이 포함된 복

www.itworld.co.kr

 

 

결론은 서버에서 관련 로직을 작성하는 것이 여러모로 확장성에는 도움이 된다는 것!(성능은 일단 잘 모르겠음..나중에 면접보면 물어봐야지)

그래서 일단은 서버에 관련 로직을 넣으려고 했으나..

 

문제는 나는 게시판 관련 로직이라 데이터를 10개씩밖에 안 가져오는데

만약 가져온 10개의 게시글 중 8개의 게시글이 삭제 게시글이라면

한 페이지에는 2개의 게시글밖에 보이지 않는 문제가 생긴다...

그래서 그냥..^__^ 간단한 로직이기도 하니 쿼리로 추가하는 걸로!

 

각설하고.....도전!!!

 

 

FanLetterJpaRepository

public interface FanLetterJpaRepository extends Repository<FanBoard, Long> {
	// 셀렉트올 + 디스팅크트 + 페치조인 + 카운팅을 하면 자동 페이징 가능
	@Query(value = "SELECT DISTINCT f FROM FanBoard f LEFT JOIN FETCH f.member WHERE f.boardRemover IS NULL", countQuery = "SELECT COUNT(DISTINCT f) FROM FanBoard f")
	Page<FanBoard> findAll(Pageable pageable);
}

페이징은 Pageable 만 매개변수로 받아오면 JpaRepository 가 자동으로 페이징을 해준다

단, 나는 게시판을 가져올 때 게시판 안에 있는 Member 엔티티도 함께 가져와야해서

member를 페치조인하고 조건문을 주는 쿼리를 직접 작성했다

페이징을 할 때 직접 쿼리를 작성할 경우, 카운트 쿼리도 반드시 작성해주어야함!

페이징 관련 쿼리는 필요 없음, Pageable 만 가져오면 Jpa가 알아서 해줌(편리 굿 ㅋ)

 

 

FanLetterService

@Override
public Page<FanBoard> listMain(Pageable pageable) {

	// 현재페이지 / 페이지사이즈(10) / id 기준 오름차순 정렬
	Pageable pageRequest = PageRequest.of(pageable.getPageNumber(),
    		pageable.getPageSize(), Sort.Direction.DESC, "id");
        
	return fanLetterJpaRepository.findAll(pageRequest);
    
}

Pageable 만 가져왔을 때 완벽하게 페이징이 되면 참 좋겠지만

나는 id 를 기준으로 오름차순 정렬이 필요하기 때문에

부득이하게 PageReuqest.of 를 사용해서

페이징 조건을 같이 넣어주었다 ^__^

 

 

FanLetterController

@GetMapping
public String fanLetterList(@PageableDefault Pageable pageable, Model model) {
	
    Page<FanBoard> fanBoards = fanLetterService.listMain(pageable);
    Page<BoardListDto> fanLetterList = fanBoards
		.map(fanboard -> new BoardListDto(fanboard));
	
    model.addAttribute("fanLetterList", fanLetterList);
    model.addAttribute("nowPage", pageable.getPageNumber());
    
	return "fanLetter/boardList";
}

페이징을 할 땐 뭔가 다른 건 필요 없이

내가 Pageable 을 컨트롤러에서 매개변수로 받아오기만 해도 자동으로 페이징이 된다

나는 DefaultValue 를 그대로 사용하기 위해 애노테이션을 붙여주었다

 

일단 서비스에서 findAll 한 리스트를 가져온다

그리고 엔티티를 그대로 반환하는 건 쓸데없이 너무 많은 데이터를 노출하는 일이니,

일단 Dto로 변환하는 작업을 한다

(람다식 써보았음 헤헷)

 

 

그러면 결과는 ?

 

요기 보면 101번 게시글이 boardRemover가 null이 아닌 삭제된 게시글인데

무사히 안 보이는 걸 볼 수 있다

밑에 숫자들 보면 페이징도 제대로 되었다구!! 야호!^____^/)

728x90