Kim VamPa

[스프링 게시판][6] 페이징 기능 구현(페이징 쿼리 적용) 본문

스프링 프레임워크/게시판 프로젝트

[스프링 게시판][6] 페이징 기능 구현(페이징 쿼리 적용)

Kim VamPa 2021. 2. 26. 22:52
728x90
반응형

Git 주소 : github.com/sjinjin7/Blog_BoardProject

목표

 

페이징 쿼리 적용

  저번 포스팅([스프링 게시판][6] 페이징 기능 구현(페이징 쿼리 정리))에서 정리한 쿼리를 활용하여 현재의 목록 페이지(list.jsp)에 각 페이지에 10개의 게시물 목록을 출력되도록 하는 것을 목표로 합니다. 페이지에 대한 제어는 이번 포스팅에서는 Controller에서 합니다. 웹 사용자가 페이지를 제어할 수 있는 인터페이스는 다음 포스팅에서 진행합니다.

 

 Oracle 프로젝트에는 'rownum 2 방식'을 MySQL 프로젝트에는 'limit 방식'을 사용합니다.

 

 

 

순서

0. 쿼리 동적제어 필요정보

1. Criter 클래스 정의

2. Mapper 작성 및 테스트

3. Service 작성 및 테스트

4. Controller 처리

5. 테스트

 

 

 

0. 쿼리 동적제어 필요정보

 저번 포스팅의 쿼리를 동적으로 동작하도록 하기 위해선 rownum 조건값과 limit 조건값이 각 상황에 맞게 변경되어야 합니다.

 

그림 1

 

 위의 표시한 값들을 제어하기 위해 2가지의 데이터가 필요로 합니다. 첫 번째는 현재 페이지(pageNum)에 대한 정보이고 두 번째는 하나의 페이지에 몇 개의 목록(amount)을 보여줄 것인지에 대한 정보입니다. 2개의 정보를 통해 페이징 쿼리문을 동작하도록 표현하면 다음과 같습니다. 

 

그림 2

 

 

1. Criteria

 페이징 쿼리를 동적 제어하기 위해 필요한 데이터 'pageNum'과 'amount'을 같이 파라미터로 전달하기 위한 용도로 Criteria 클래스(class)를 작성합니다. 각각의 데이터를 분리하여 파라미터로 전달해도 되지만 연관성 있는 데이터를 같이 관리함으로써 관리하기 편하고 재사용성에도 장점 때문에 클래스를 작성하였습니다. Criteria는 '기준'이라는 뜻인데 '검색의 기준'이라는 의미에서 클래스명으로 사용하였습니다.

 

 com.vam.model 패키지에 Criteria.java 클래스를 생성 후 아래의 코드를 작성합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
    /* 현재 페이지 */
    private int pageNum;
    
    /* 한 페이지 당 보여질 게시물 갯수 */
    private int amount;
    
    /* 기본 생성자 -> 기봅 세팅 : pageNum = 1, amount = 10 */
    public Criteria() {
        this(1,10);
    }
    
    /* 생성자 => 원하는 pageNum, 원하는 amount */
    public Criteria(int pageNum, int amount) {
        this.pageNum = pageNum;
        this.amount = amount;
    }
 

 

그림 3

 

- '현재 페이지'와 '게시물 개수' 변수(pageNum, amount)를 선언하였습니다.

 

- 파라미터 없이 Criteria 클래스를 호출하였을 때는 기본적으로 pageNum은 1, amount는 10을 가지도록 생성자를 작성하였습니다.

 

- 파라미터와 함께 Criterial를 호출하게 되면 파라미터의 값이 각각 pageNum과 amount 값에 저장되도록 생성자를 작성하였습니다.

 

 

 

 위의 코드를 작성하였다면 변수 pageNum, amount에 대해 getter/setter, toString 메소드를 생성해줍니다.

 

그림 4

 

MySQL 프로젝트 Criteria

 

 MySQL 프로젝트 경우 쿼리문에 limit을 활용할 것이기 때문에 Criteria.java 클래스에 추가적인 변수와 설정을 해주어야 합니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
    /* 현재 페이지 */
    private int pageNum;
    
    /* 한 페이지 당 보여질 게시물 갯수 */
    private int amount;
    
    /* 스킵 할 게시물 수( (pageNum-1) * amount ) */
    private int skip;
    
    /* 기본 생성자 -> 기봅 세팅 : pageNum = 1, amount = 10 */
    public Criteria() {
        this(1,10);
        this.skip = 0;
    }
    
    /* 생성자 => 원하는 pageNum, 원하는 amount */
    public Criteria(int pageNum, int amount) {
        this.pageNum = pageNum;
        this.amount = amount;
        this.skip = (pageNum-1)*amount;
    }
 

 

- pgaeNum과 amount 변수와 더불어 skip 변수를 선언합니다. 쿼리 문의 limit에서 사용할 스킵(skip) 개수를 미리 Java단계에서 처리 후 넘겨주기 위함입니다. 

 

- 생성자에도 skip 값이 연산되어 저장되도록 코드를 추가하였습니다.

 

 

 3개의 변수 모두 getter/setter, toString 메소드를 추가해줍니다. setAmount(), setPageNum() 메소드를 호출한다는 것은 amount, pageNum 값을 변경한다는 것을 의미합니다. 따라서 skip의 값또한 변경되어야 하기때문에 해당 메소드 구현부에 skip값이 변경되도록 코드를 추가합니다.

 

그림 6

 

 

 

2. Mapper 작성 및 테스트

BoardMapper.java 인터페이스

 

 페이징을 적용한 게시물 목록을 띄우는 쿼리를 실행할 메소드 선언부를 작성합니다.

 

1
2
3
 
    /* 게시판 목록(페이징 적용) */
    public List<BoardVO> getListPaging(Criteria cri);

 

그림 7

 

- 기존 '게시물 목록(getList())' 메소드 역할을 하면서 단지 쿼리만 조금 수정되는 것이기 때문에 반환 타입은 동일하게 List <BoardVO>를 작성합니다. 

 

- pageNum, amount의 정보를 DB에 전달하기 위해서 Criteria 클래스를 파라미터로 부여합니다.

 

 

BoardMapper.xml 

 

 인터페이스에서 작성한 메소드가 실행할 쿼리를 작성합니다. 아래의 코드와 같이 <select> 태그와 쿼리를 작성합니다. "<![CDATA[ ]]>"는 xml 파일 내의 쿼리 중 부등호가 사용될 때 해당 부등호를 태그로 인식하지 않도록 하기 위해서 사용하였습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    <!-- Oracle -->
    <!-- 게시물 목록(페이징) -->
    <!-- 게시물 목록(페이징) -->
    <select id="getListPaging" resultType="com.vam.model.BoardVO">
    
    <![CDATA[
        
        select bno, title, content, writer, regdate, updatedate from(
        
                select /*+INDEX_DESC(vam_board pk_board) */ rownum  as rn, bno, title, content, writer, regdate, updatedate
                  
                from vam_board where rownum <= #{pageNum} * #{amount}) 
                
        where rn > (#{pageNum} -1) * #{amount}
    
    ]]>
    
    </select>
 
 
    <!-- MySQL-->
    <!-- 게시물 목록(페이징) -->
    <select id="getListPaging" resultType="com.vam.model.BoardVO">
    
        select * from (
                select bno, title, writer, regdate, updatedate  
                from vam_board order by bno desc) as T1 
        <!-- limit ((${pageNum}-1)*${amount}), ${amount} -->
        limit #{skip},#{amount}
    
    </select>
 

 

그림 8

 

그림 9

 

 

Mapper 테스트

 

 작성한 Mapper 메소드를 테스트합니다. src/test/java 경로의 com.vam.mapper 패키지에 있는 BoardMapperTests.java 에 아래의 코드를 작성하여 Junit 테스트합니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
 
        /* 게시판 목록(페이징 적용)테스트 */
     @Test
     public void testGetListPaging() {
         
         Criteria cri = new Criteria();
                          
         List list = mapper.getListPaging(cri);
         
         list.forEach(board -> log.info("" + board));
     }
 

 

 

 

 정상적으로 동작을 한다면 pageNum값을 바꿔가면서 순서대로 10개씩 출력이 되는지 확인합니다.

 

그림 12

 

그림 13

 

그림 14

 

그림 15

 

 

3. Service 작성 및 테스트

BoardService.java 인터페이스

 

 BoardService.java 인터페이스에 Mapper 메소드를 호출하기위한 메소드 선언부를 추가합니다.

 

1
2
3
4
 
    /* 게시판 목록(페이징 적용) */
    public List<BoardVO> getListPaging(Criteria cri);
 

 

그림 16

 

 

BoardServiceImpl.java

 

 BoardServiceImpl.java에서 인터페이스에서 선언한 메소드를 구현합니다.

 

1
2
3
4
5
6
7
8
 
    /* 게시판 목록(페이징 적용) */
    @Override
    public List<BoardVO> getListPaging(Criteria cri) {
        
        return mapper.getListPaging(cri);
    }    
 

 

그림 17

 

 

BoardServiceTests.java

 

 작성한 Service 메소드를 junit 테스트 합니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
    /* 게시판 조회(페이징 적용) */
    @Test
    public void testGetListPaging() {
        
        Criteria cri = new Criteria();
        
        List list = service.getListPaging(cri);
        
        list.forEach(board -> log.info("" + board));
        
        
    }
 

 

그림 18

 

그림 19

 

 

4. Controller 처리

 기존 "/board/list" url 매핑 메소드를 주석처리하거나 삭제 후 아래의 코드를 추가합니다. (기존 메소드를 활용하여 수정해도 상관없습니다.)

 

1
2
3
4
5
6
7
8
9
10
11
 
    /* 게시판 목록 페이지 접속(페이징 적용) */
    @GetMapping("/list")
    public void boardListGET(Model model, Criteria cri) {
        
        log.info("boardListGET");
        
        model.addAttribute("list", bservice.getListPaging(cri));
        
    }
 

 

그림 20

 

 - 기존 메소드와 거의 동일하지만 2가지가 다릅니다.

 

 - Criteria 클래스를 파라미터로 추가하였습니다. (보고자 하는 페이지의 정보를 얻기 위해서입니다.)

 

 - 기존에 사용하던 getList() 메소드 대신 새로 작성한 getListPaging()메소드를 사용하였습니다.

 

 

 

5. 테스트

 "/board/list" 페이지가 정상적으로 출력되는지 테스트합니다.

 

그림 21

 

정상적으로 출력이 되는 걸 확인하였다면 쿼리 스트링을 통해 pageNum과 amout값을 직접 삽입하여 작동하는지 테스트합니다.

 

그림 22

 

그림 23

 

 

REFERENCE

 

 

 

DATE

  • 2020.02.26
728x90
반응형
Comments