페이징 처리는 다음과 같은 과정으로 이루어집니다:
- 컨트롤러에서 클라이언트의 page 파라미터를 받아 서비스 계층에 전달합니다.
- 서비스 계층에서 pageNumber를 이용해 offset을 계산하고, 매퍼에 offset과 pageSize를 전달하여 데이터를 조회합니다.
- MyBatis 매퍼에서는 SQL 쿼리에서 LIMIT과 OFFSET을 사용해 페이징 처리를 합니다.
- Thymeleaf 뷰에서 현재 페이지와 총 페이지 수를 이용해 이전/다음 페이지로 이동할 수 있는 링크를 생성합니다.
이 과정을 통해 클라이언트에 필요한 데이터만 전송하여 성능을 최적화할 수 있습니다.
Spring Boot와 MyBatis를 사용하여 `board` 테이블에 대한 페이징 처리 예제를 작성해 보겠습니다. 이 예제에서는 `board` 테이블을 사용하고, Gradle과 Thymeleaf를 사용하여 프론트엔드를 구현합니다.
### 1. Gradle 설정
먼저, `build.gradle` 파일에 필요한 의존성을 추가합니다.
```gradle
plugins {
id 'org.springframework.boot' version '2.7.17'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.4'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
runtimeOnly 'mysql:mysql-connector-java'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
```
### 2. 데이터베이스 설정
`application.properties` 또는 `application.yml` 파일에 MySQL 데이터베이스 설정을 추가합니다.
```properties
spring.datasource.url=jdbc:mysql://localhost:3306/your_database_name?useSSL=false&serverTimezone=UTC
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.datasource.driver-class-name=cohttp://m.mysql.cj.jdbc.Driver
mybatis.mapper-locations=classpath:mapper/*.xml
spring.jpa.show-sql=true
```
### 3. 데이터베이스 테이블 생성
`board` 테이블을 생성하는 SQL 스크립트입니다.
```sql
CREATE TABLE board (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(100) NOT NULL,
content TEXT NOT NULL,
writer VARCHAR(50) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
```
### 4. 매퍼 인터페이스와 XML 설정
#### 매퍼 인터페이스
```java
@Mapper
public interface BoardMapper {
List<Board> listAll(@Param("offset") int offset, @Param("pageSize") int pageSize);
int count();
}
```
#### 매퍼 XML 설정
`src/main/resources/mapper/BoardMapper.xml` 파일을 생성하고 다음 내용을 추가합니다.
```xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cohttp://m.example.mapper.BoardMapper">
<select id="listAll" resultType="cohttp://m.example.domain.Board">
SELECT
id,
title,
content,
writer,
created_at,
updated_at
FROM board
ORDER BY created_at DESC
LIMIT #{pageSize} OFFSET #{offset}
</select>
<select id="count" resultType="int">
SELECT COUNT(*) FROM board
</select>
</mapper>
```
### 5. 도메인 클래스
`src/main/java/com/example/domain/Board.java` 파일을 생성하고 다음 내용을 추가합니다.
```java
package cohttp://m.example.domain;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class Board {
private Long id;
private String title;
private String content;
private String writer;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
```
### 6. 서비스 계층
`src/main/java/com/example/service/BoardService.java` 파일을 생성하고 다음 내용을 추가합니다.
```java
package com.example.service;
import cohttp://m.example.domain.Board;
import cohttp://m.example.mapper.BoardMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class BoardService {
private final BoardMapper boardMapper;
private static final int PAGE_SIZE = 10;
public List<Board> list(int pageNumber) {
int offset = (pageNumber - 1) * PAGE_SIZE;
return boardMapper.listAll(offset, PAGE_SIZE);
}
public int count() {
return boardMapper.count();
}
}
```
### 7. 컨트롤러
`src/main/java/com/example/controller/BoardController.java` 파일을 생성하고 다음 내용을 추가합니다.
```java
package com.example.controller;
import cohttp://m.example.domain.Board;
import com.example.service.BoardService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Controller
@RequiredArgsConstructor
public class BoardController {
private final BoardService boardService;
@GetMapping("/board/list")
public String list(@RequestParam(value = "page", defaultValue = "1") int pageNumber, Model model) {
List<Board> boards = boardService.list(pageNumber);
int totalCount = boardService.count();
int totalPages = (int) Math.ceil((double) totalCount / 10);
model.addAttribute("boards", boards);
model.addAttribute("currentPage", pageNumber);
model.addAttribute("totalPages", totalPages);
return "board/list";
}
}
```
### 8. Thymeleaf 뷰
`src/main/resources/templates/board/list.html` 파일을 생성하고 다음 내용을 추가합니다.
```html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Board List</title>
</head>
<body>
<h1>Board List</h1>
<table>
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Writer</th>
<th>Created At</th>
</tr>
</thead>
<tbody>
<tr th:each="board : ${boards}">
<td th:text="${board.id}"></td>
<td th:text="${board.title}"></td>
<td th:text="${board.writer}"></td>
<td th:text="${board.createdAt}"></td>
</tr>
</tbody>
</table>
<div>
<span th:text="'Page ' + ${currentPage} + ' of ' + ${totalPages}"></span>
<div>
<a th:if="${currentPage > 1}" th:href="@{/board/list(page=${currentPage - 1})}">Previous</a>
<a th:if="${currentPage < totalPages}" th:href="@{/board/list(page=${currentPage + 1})}">Next</a>
</div>
</div>
</body>
</html>
```
'학습 > Java_Spring' 카테고리의 다른 글
java로 한글(HWP)파일 읽어서 출력하기 (0) | 2024.06.24 |
---|---|
자주 사용한 애너테이션 정리 (0) | 2024.06.24 |
Spring Boot에서 하나의 JAR 파일로 빌드하고, 각기 다른 포트로 'admin'과 'user' 컨트롤러를 구분하기 (0) | 2024.06.24 |
Spring Boot 애플리케이션에서 CORS(Cross-Origin Resource Sharing)를 설정 (0) | 2024.06.23 |
openjdk 설치 (0) | 2024.06.21 |