스프링부트 페이징 구현 수업 정리 1
denpendencies 수정
타임리프 사용할것이니 아래 denpendencies 추가
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:3.1.0'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
application.properties 수정
파일 저장설정을 해주자. 저장경로에 H2 DB파일이 세이브될것이다.
Member.java
package com.example.demo.entity;
import javax.persistence.*;
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer num;
@Column
private String name;
@Column
private String id;
@Column
private String phone;
@Column
private Integer age;
// Getters and Setters
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
// Constructor
public Member() { }
public Member(Integer num, String name, String id, String phone, Integer age) {
super();
this.num = num;
this.name = name;
this.id = id;
this.phone = phone;
this.age = age;
}
// toString()
@Override
public String toString() {
return "Member [num=" + num + ", name=" + name + ", id=" + id + ", phone=" + phone + "]";
}
}
MemberDTO.java
package com.example.demo.dto;
import com.example.demo.entity.Member;
public class MemberDTO {
// Fields
private Integer num;
private String name;
private String id;
private String phone;
private Integer age;
// Getters and Setters
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
// toString()
@Override
public String toString() {
return "MemberDTO [num=" + num + ", name=" + name + ", id=" + id + ", phone=" + phone + "]";
}
// toEntity()
public Member toEntity() {
return new Member( num, name, id, phone, age );
}
}
MemberRepository.java
package com.example.demo.repository;
import com.example.demo.entity.Member;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MemberRepository extends JpaRepository <Member, Integer> {
}
JpaController.java
package com.example.demo.controller;
import com.example.demo.dto.MemberDTO;
import com.example.demo.entity.Member;
import com.example.demo.repository.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@Controller
public class JpaController {
@Autowired
private MemberRepository memberRepository;
@RequestMapping(value="/jpa/memberWrite", method= RequestMethod.GET)
public String memberWrite(
@RequestParam(value="num", required = false) Integer num,
Model model) {
if(num != null){
//기존회원 -> 수정
}else{
//신규회원
System.out.println("신규");
model.addAttribute("memberDTO" , new MemberDTO());
model.addAttribute("formTitle", "Registration");
}
return "jpa/memberWriteForm";
}
@RequestMapping(value="/jpa/memberWrite", method= RequestMethod.POST)
public String memberWrite(MemberDTO memberDTO, Model model) {
try {
System.out.println(memberDTO);
//memberDTO를 -> Entity로 변경
Member save = memberDTO.toEntity();
//Repository를 이용한 DB작업
Member saved = memberRepository.save(save);
System.out.println(saved);
}catch(Exception e) {
e.printStackTrace();}
return "redirect:/";
}
//Jpa/memberList
@RequestMapping(value="/jpa/memberList", method= RequestMethod.GET)
public String memberList(Model model) {
List<Member> members = memberRepository.findAll();
model.addAttribute("members", members);
return "jpa/memberList";
}
}
index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>시작페이지</h1>
<button onclick="location.href='/jpa/memberList'">회원리스트</button>
<button onclick="location.href='/jpa/memberWrite'">회원등록</button>
memberList.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>memberList</title>
<style>
ul > li {
display: inline-block;
border: 0px solid;
padding: 10px;
}
ul {
margin-left: -50px;
}
</style>
</head>
<body>
<table cellpadding=10 border=1 width="800">
<thead>
<tr>
<th width="50">#</th>
<th>Name</th>
<th>ID</th>
<th>Phone</th>
<th>Age</th>
<th>Edit</th>
<th>Del</th>
<th>Del</th>
</tr>
</thead>
<tbody>
<tr th:each="member : ${members}">
<th th:text="${member.num}">1</th>
<th><a href="#" th:href="@{/jpa/memberDetail( num=${member.num} )}" th:text="${member.name}">홍길동</a></th>
<th th:text="${member.id}">mr.hong</th>
<th th:text="${member.phone}">010-123-5678</th>
<th th:text="${member.age}">20</th>
<th><a href="#" th:href="@{/jpa/memberWrite( num=${member.num} )}">수정</a></th>
<th><a href="#" th:href="@{/jpa/memberDelete( num=${member.num} )}">삭제(바로 삭제)</a></th>
<th><a href="#none" th:onclick="btnDel( [[${member.num}]] );" style="color: #ff0000">삭제(확인 후 삭제)</a></th>
</tr>
</tbody>
</table>
</body>
</html>
콘솔창에 뜬 jdbc url 복사
h2-console로 url붙이기 아까 입력했던 Name, Password 입력후 Connect
table 생성이 확인된다.
아까 지정해주었던 세이브파일 경로 들어가보면 DBfile확인 가능하다.
위 코드 출력화면▼
페이지를 구현하기전 기능을 알아보자.
//Jpa/memberList
@RequestMapping(value="/jpa/memberList", method= RequestMethod.GET)
public String memberList(Model model,
Pageable pageable) {
//page기능만들기
//spring boot는 페이지기능을 만들수있는 클래스를 제공
//pageable 페이지 정보를 저장하는객체
//Page 검색된 데이터저장
Page<Member> members = memberRepository.findAll(pageable);
System.out.println("전체 페이지 개수="+members.getTotalPages());
System.out.println("전체 레코드 개수="+members.getTotalElements());
System.out.println("현재 페이지 개수="+members.getNumber());
System.out.println("한페이지에 보여주는 글 개수="+members.getSize());
System.out.println("정렬="+members.getSort());
System.out.println("number,size,sort 여러가지정보="+members.getPageable());
model.addAttribute("members", members);
return "jpa/memberList";
}
해당 url을 들어가면 system.out으로 콘솔창에 페이지 정보들이 출력된다.
쿼리스트링을 넣어보면 해당 정보만 출력되는 것을 확인할수있다.
index.html 수정
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>시작페이지</h1>
<button onclick="location.href='/jpa/memberList'">회원리스트</button>
<button th:onclick="|location.href='@{/jpa/memberList(page=0, size=5)}'|">회원 리스트 1번 페이지</button><br>
<button onclick="location.href='/jpa/memberWrite'">회원등록</button>
회원리스트에서는 페이징이 적용되지않는다.
회원리스트 1번페이지에서 페이징기능을 확인할수있다.
타임리프 Literal Substitions 문자열조합
매번 작은따옴표로 감싸서 더하기를 하는 것도 번거롭다, 이때 아래와 같이 리터럴 대체 문법을 사용하면 작은따옴표도 더하기도 필요 없이 대체 문법 안에 있는 리터럴과 변수들을 편리하게 사용할 수 있다
<button th:onclick="|location.href='@{/jpa/memberList(page=0, size=5)}'|">회원 리스트 1번 페이지</button><br>
memberList.html 수정
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>memberList</title>
<style>
ul > li {
display: inline-block;
border: 0px solid;
padding: 10px;
}
ul {
margin-left: -50px;
}
</style>
</head>
<body>
<table cellpadding=10 border=1 width="800">
<thead>
<tr>
<th width="50">#</th>
<th>Name</th>
<th>ID</th>
<th>Phone</th>
<th>Age</th>
<th>Edit</th>
<th>Del</th>
<th>Del</th>
</tr>
</thead>
<tbody>
<tr th:each="member : ${members}">
<th th:text="${member.num}">1</th>
<th><a href="#" th:href="@{/jpa/memberDetail( num=${member.num} )}" th:text="${member.name}">홍길동</a></th>
<th th:text="${member.id}">mr.hong</th>
<th th:text="${member.phone}">010-123-5678</th>
<th th:text="${member.age}">20</th>
<th><a href="#" th:href="@{/jpa/memberWrite( num=${member.num} )}">수정</a></th>
<th><a href="#" th:href="@{/jpa/memberDelete( num=${member.num} )}">삭제(바로 삭제)</a></th>
<th><a href="#none" th:onclick="btnDel( [[${member.num}]] );" style="color: #ff0000">삭제(확인 후 삭제)</a></th>
</tr>
</tbody>
</table>
<p>
총 레코드 갯수 <span style="color: red; font-weight: bold" th:text="${members.totalElements}">4</span>
현재 페이지 <span style="color: green; font-weight: bold" th:text="${members.pageable.pageNumber+1}">1</span> /
총 페이지 <span style="color: blue; font-weight: bold" th:text="${members.totalPages}">5</span>
</p>
<ul>
<li>
<th:block th:if="${ members.pageable.pageNumber+1 == 1 }">
<span style="color: #999">Previous</span>
</th:block>
<th:block th:unless="${ members.pageable.pageNumber+1 == 1 }">
<a href="#" th:href="@{/jpa/memberList( page=${members.pageable.pageNumber-1},size=3)}">Previous</a>
</th:block>
</li>
<li>/</li>
<li>
<th:block th:if="${ members.totalPages == members.number+1 }">
<span style="color: #999">Next</span>
</th:block>
<th:block th:unless="${ members.totalPages == members.number+1 }">
<a href="#" th:href="@{/jpa/memberList( page=${members.number}+1, size=3)}">Next</a>
</th:block>
</li>
</ul>
</body>
</html>
마지막으로 검색기능을 넣어보자
JpaController.java 수정
//Jpa/memberList
@RequestMapping(value="/jpa/memberList", method= RequestMethod.GET)
public String memberList(Pageable pageable,
@RequestParam(value="searchKeyword",required=false,defaultValue="")
String searchKeyword, Model model) {
//page기능만들기
//spring boot는 페이지기능을 만들수있는 클래스를 제공
//pageable 페이지 정보를 저장하는객체
//Page 검색된 데이터저장
Page<Member> members = memberRepository.findByNameContaining(searchKeyword, pageable);
model.addAttribute("members", members);
return "jpa/memberList";
}
MemberRepository.java 추가
public interface MemberRepository extends JpaRepository <Member, Integer> {
Page<Member> findByNameContaining(String searchKeyword, Pageable pageable);
}
memberList.html 추가
<h2>Member List</h2>
<p><a href="/">Main</a> / 현재 <span th:text="${#lists.size(members)}" style="font-weight: bold">10</span>명의 회원정보가 등록되었습니다.</p>
<form
style="padding: 10px; border: 0px solid; width: 780px; display: flex; justify-content: flex-end"
th:action="@{/jpa/memberList}" method="GET">
Name or ID 검색
<input type="text" id="searchKeyword" name="searchKeyword" placeholder="검색어 입력" autocomplete="off">
<button type="submit">Search</button>
</form>
자세한설명링크 : https://pebble-twine-b24.notion.site/71553750235e4478842af2c33baa97a8
'STUDY > SpringBoot' 카테고리의 다른 글
[Springboot] 22-09-29 삭제·상세·수정 기능 수업 -3 (0) | 2022.09.29 |
---|---|
[Springboot] 22-09-29 페이징 기능 수업 -2 (0) | 2022.09.29 |
[SpringBoot] 22-09-27 Thymeleaf 문법 총 정리 (0) | 2022.09.27 |
[SpringBoot] 22-09-26 Login CRUD 수업 (0) | 2022.09.26 |
[SpringBoot] 22-09-23 템플릿엔진 Mustache (1) | 2022.09.23 |