mybatis Pagination

최혜미·2023년 6월 4일

Backend

목록 보기
6/8

page1 프로젝트

https://github.com/ghrltjdtprbs/Backend

1) 액션 메소드의 파라미터 객체

액션 메소드의 파라미터가 객체일 경우에, 다음과 같은 일이 자동으로 일어난다.

  • 그 객체에 request parameter 데이터가 자동으로 채워진다.

이때 그 객체의 set 메소드 이름과 request parameter 데이터 이름이 일치하는 것만 채워진다.

예: pg=3&od=4

void setPg(int value);

void setOd(int value);

  • 그 파라미터 객체가 모델에 자동으로 채워진다.

이때 모델 데이터 이름은, 변수명이 아니고, 그 클래스 이름이다. (첫 글자만 소문자로 바꿈)

예:

@RequestMapping("list")

public String list(Pagination p) {

model.addAttribute("pagination", p); // 이 코드를 생략해도 된다. 자동으로 실행되기 때문이다.

. . .

}

2) mybatis 로그

디버깅 할 때, mybatis 에 의해서 실행되는 SQL 명령과 파라미터를 확인해 보고 싶은 경우가 있다.

logging.level.net.skhu.mapper.StudentMapper=DEBUG

application.properties 파일에 위 설정을 추가하면

net.skhu.mapper.StudentMapper 에서 실행되는 SQL 명령들을

이클립스 console 창에서 확인할 수 있다.

3) mysql LIMIT

SELECT *

FROM student

LIMIT 10, 15

student 테이블에서 모든 레코드를 조회하는 것이 아니고,

10 번째 레코드부터 시작하여 15 개의 레코드만 조회한다.

SELECT *

FROM student

LIMIT 0, 15

student 테이블에서 0 번째 레코드부터 시작하여 15 개의 레코드만 조회한다.

레코드 번호가 0 번 부터 시작됨에 주의하자.

4) pagination URL

현재 페이지 번호가 URL의 query string에 포함되어야 한다.

그리고 페이지 크기를 쉽게 바꿀 수 있도록, 페이지 크기도 URL의 query string에 포함되는 것이 좋다.

예를 들어 현재 페이지가 3, 페이지 크기가 15 이라면.

학생 목록 페이지 URL

http://localhost:8088/student/list?pg=3&sz=15

학생 등록 페이지 URL

http://localhost:8088/student/create?pg=3&sz=15

학생 수정 페이지 URL

http://localhost:8088/student/edit?id=5&pg=3&sz=15

저장하고 목록 페이지로 나왔을 때,

삭제하고 목록 페이지로 나왔을 때,

이전의 페이지 번호로 이동할 수 있으려면,

pagination을 구현한 모든 페이지 URL의 query string에 pagination 정보가 포함되어야 한다.

pg=3&sz=15

위의 URL들을 서버에 요청하면, pagination 정보가 request parameter로 전달된다.

이 pagination 정보 request parameter를 전달받기위한 모델 객체가 필요하다.

그 객체의 클래스 이름을 Pagination 으로 하자.

Pagination 모델 클래스가 필요하다.

5) request parameter 값으로 분기하기

request mapping

@PostMapping(value="edit", params="cmd=save")

public String edit(Model model, Student student, Pagination pagination) {

...

}


@PostMapping(value="edit", params="cmd=delete")

public String delete(Model model, @RequestParam("id") int id, Pagination pagination) {

...

}

위의 두 액션 메소드를 호출하는 URL은 동일하다.

POST 방식의 "student/edit" 이다.

그런데 request parameter에 cmd=save 값이 들어있으면, edit 메소드가 호출되고

request parameter에 cmd=delete 값이 들어있으면, delete 메소드가 호출된다.

submit 버튼

<button type="submit" class="btn" name="cmd" value="save">저장</button>

<button type="submit" class="btn" name="cmd" value="delete" data-confirm-delete>삭제</button>

저장

삭제
저장 버튼, 삭제 버튼 둘 다 submit 버튼이다.

따라서 이 버튼 중의 하나를 클릭하면, POST 방식으로 현재 URL이 서버에 요청된다.

이때 클릭된 submit 버튼의 name, value 값도 request parameter가 되어 서버에 전송된다.

이 값을 보면 어떤 버튼이 눌려졌는지 알 수 있다.

2) Department.java

src/main/java/net/skhu/dto/Department.java

package net.skhu.dto;
import lombok.Data;


@Data

public class Department {

int id;

String name;

}

3) Student.java

src/main/java/net/skhu/dto/Student.java

package net.skhu.dto;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size;
import lombok.Data;

@Data
public class Student {

int id;

@NotEmpty
@NotBlank
@Size(min=8, max=9)
String studentNo;

@NotEmpty
@NotBlank
String name;
int departmentId;
String sex;
String phone;

@Email
String email;

String departmentName;

}

Student DTO 클래스, Student 모델 클래스 구분하지 않고

이 클래스를 DTO로도 사용하고, 모델로도 사용하려고 함.

그래서 spring form validation 어노테이션을 붙였다.

4) Pagination.java 모델

src/main/java/net/skhu/model/Pagination.java

package net.skhu.model;
import lombok.Data;

@Data
public class Pagination {

int pg = 1; // 현재 페이지 번호
int sz = 15; // 페이지 당 레코드 수
int recordCount; // 전체 레코드 수

public int getFirstRecordIndex() {

return (pg - 1) * sz;

}

public String getQueryString() {

return String.format("pg=%d&sz=%d", pg, sz);

 }
}

페이지 단위 조회 기능을 구현하기 위해서,

액션 메소드와 뷰 사이에 전달되어야 하는 정보를 담은 객체이다.

pg 속성과 sz 속성

pg 속성: 현재 페이지 번호 (1부터 시작함)

sz 속성: 페이지 크기 (한 페이지의 레코드 수)

recordCount 속성: 전체 레코드 수

페이지 하단에 페이지 번호 목록을 출력하려면, 레코드 수를 알아야 함.

http://localhost:8088/student/list?pg=3&sz=15

위의 URL을 서버에 요청했을 때,

query string 값들은 request parameter가 되어 서버에 전송된다.

이 request parameter 값은 액션 메소드의 파라미터 Pagination 객체에 채워진다.

getFirstRecordIndex 메소드

pg 번째 페이지의 첫 레코드의 인덱스를 계산하는 메소드 이다.

예를 들어 페이지 당 레코드 수 즉 sz 값이 15일 때,

1번 페이지의 첫 레코드의 인덱스는 0,

2번 페이지의 첫 레코드의 인덱스는 15,

3번 페이지의 첫 레코드의 인덱스는 30 이다.

이 값을 계산하는 메소드이다.

getQueryString 메소드

"pg=%d&sz=%d" 형태의 URL query string을 출력하기 위한 메소드이다.

뷰에서 이 메소드의 리턴값을 출력하려면 ${ pagination.queryString } 이렇게 하면 된다.

서버에서 뷰를 출력할 때,

학생 등록 버튼은 a 태그는 다음과 같이 출력되어야 한다.

<a href="create?pg=3&sz=15">

위와 같이 출력하기 위한 소스 코드는 다음과 같다.

<a href="create?${pagination.queryString}">

학생 목록에서 tr 태그는 다음과 같이 출력되어야 한다.

<tr data-url="edit?id=5&pg=3&sz=15">

위와 같이 출력하기 위한 소스 코드는 다음과 같다.

<tr data-url="edit?id=5&${pagination.queryString}">

목록으로 되돌아가기 위한 redirect URL은 다음과 같아야 한다.

return "redirect:list?pg=3&sz=15";

그때 그때 달라지는 페이지 번호를 위와 같이 3으로 고정할 수는 없으니, 다음과 같이 구현해야 한다.

return "redirect:list?" + pagination.getQueryString();

JSP 부분과 java 소스 코드가 다르게 구현되는 점에 주의하자.

0개의 댓글