https://github.com/ghrltjdtprbs/Backend
액션 메소드의 파라미터가 객체일 경우에, 다음과 같은 일이 자동으로 일어난다.
이때 그 객체의 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); // 이 코드를 생략해도 된다. 자동으로 실행되기 때문이다.
. . .
}
디버깅 할 때, mybatis 에 의해서 실행되는 SQL 명령과 파라미터를 확인해 보고 싶은 경우가 있다.
logging.level.net.skhu.mapper.StudentMapper=DEBUG
application.properties 파일에 위 설정을 추가하면
net.skhu.mapper.StudentMapper 에서 실행되는 SQL 명령들을
이클립스 console 창에서 확인할 수 있다.
SELECT *
FROM student
LIMIT 10, 15
student 테이블에서 모든 레코드를 조회하는 것이 아니고,
10 번째 레코드부터 시작하여 15 개의 레코드만 조회한다.
SELECT *
FROM student
LIMIT 0, 15
student 테이블에서 0 번째 레코드부터 시작하여 15 개의 레코드만 조회한다.
레코드 번호가 0 번 부터 시작됨에 주의하자.
현재 페이지 번호가 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 모델 클래스가 필요하다.
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가 되어 서버에 전송된다.
이 값을 보면 어떤 버튼이 눌려졌는지 알 수 있다.
src/main/java/net/skhu/dto/Department.java
package net.skhu.dto;
import lombok.Data;
@Data
public class Department {
int id;
String name;
}
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 어노테이션을 붙였다.
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 소스 코드가 다르게 구현되는 점에 주의하자.