Spring (페이지 표시 효과, 페이지 이벤트 처리, 조회 페이지로 이동, 조회에서 목록, 수정 / 삭제 처리 후 페이지 이동, 검색/필터링 조건 정의)
1. 페이지 표시 효과
<c:forEach var="num" begin="${responseDTO.start}" end="${responseDTO.end}">
<li class="page-item ${responseDTO.page == num ? "active" : ""}"><a class="page-link" href="#">${num}</a></li>
</c:forEach>
- list.jsp num 부분 코드 추가
2. 페이지의 이벤트 처리
<li class="page-item">
<a class="page-link" data-num="${responseDTO.start - 1}">Previous</a>
</li>
- Previous에 data-num 속성 추가
<c:forEach var="num" begin="${responseDTO.start}" end="${responseDTO.end}">
<li class="page-item ${responseDTO.page == num ? "active" : ""}">
<a class="page-link" data-num="${num}">${num}</a></li>
</c:forEach>
- num 부분에 코드 한 줄 추가
<a class="page-link" data-num="${responseDTO.end + 1}">Next</a>
- Next에도 코드 추가
- 서버 재 실행 후 list 11페이지에서 페이지 소스 보기로 잘 출력 되는 지 확인
</ul>
</div>
<script>
document.querySelector('.pagination').addEventListener('click', function (e) {
e.preventDefault();
e.stopPropagation();
const target = e.target;
if (target.tagName !== 'A') {
return;
}
const num = target.getAttribute('data-num');
self.location = `/todo/list?page=\${num}`; // 백틱을 이용해서 템플릿 처리
})
</script>
- ul이 끝나는 시점에 위 코드 추가
- Previous, Next 클릭 시 페이지 이동
3. 조회 페이지로 이동
package com.example.spring_project_02.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.Positive;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageRequestDTO {
@Builder.Default
@Min(value = 1)
@Positive
private int page = 1;
@Builder.Default
@Min(value = 10)
@Max(value = 100)
@Positive
private int size = 10;
private String link;
public int getSkip() {
return (page - 1) * size;
}
public String getLink() {
if (link == null) {
StringBuilder builder = new StringBuilder();
builder.append("page=" + this.page);
builder.append("&size=" + this.size);
link = builder.toString();
}
return link;
}
}
- PageRequestDTO에 위 코드 추가
<th scope="row">${dto.tno}</th>
<td><a href="/todo/read?tno=${dto.tno}&${PageRequestDTO.link}" class="text-decoration-none"> ${dto.title}</a></td>
<td>${dto.writer}</td>
- list.jsp에 pageRequestDTO.link 설정 추가
- URL에 페이지번호 제대로 출력 되는 지 확인
4. 조회에서 목록으로
@GetMapping({"/read", "/modify"})
public void read (Long tno, PageRequestDTO pageRequestDTO ,Model model) {
// 1) request로 전달 받은 tno를 서비스에 전달해서 2) TodoDTO를 반환받아서 3) View에 전달
TodoDTO todoDTO = todoService.getOne(tno);
log.info(todoDTO);
model.addAttribute("dto", todoDTO);
}
- TodoController에 코드 추가
<script>
document.querySelector(".btn-primary").addEventListener("click", function () {
self.location = "/todo/modify?tno=" + ${dto.tno};
});
document.querySelector(".btn-secondary").addEventListener("click", function () {
self.location = "/todo/list?${pageRequestDTO.link}";
})
</script>
- read.jsp에 위 코드 추가
- 서버 재 가동 후 > 게시물 클릭 > list 눌렀을 때 > 다시 페이지 이동 확인
<script>
const frmView = document.querySelector("form");
document.querySelector('.btn-danger').addEventListener('click', function () {
frmView.action = '/todo/remove';
frmView.method = 'post';
frmView.submit();
})
document.querySelector('.btn-primary').addEventListener('click', function (e) {
frmView.action = '/todo/modify';
frmView.method = 'post';
frmView.submit();
})
document.querySelector('.btn-secondary').addEventListener('click', function (e) {
self.location = '/todo/list?${pageRequestDTO.link}'
})
</script>
- modify.jsp에 스크립트 코드 추가
<script>
document.querySelector(".btn-primary").addEventListener("click", function () {
self.location = "/todo/modify?tno=" + ${dto.tno} + `&${pageRequestDTO.link}`;
});
- read.jsp에 스크립트 코드 추가
5. 수정 / 삭제 처리 후 페이지 이동
<form action="/todo/modify" method="post">
<input type="hidden" name="page" value="${pageRequestDTO.page}">
<input type="hidden" name="size" value="${pageRequestDTO.size}">
- modify.jsp에 위 코드 추가
- 서버 재 실행 후 > 9번페이지 > 젤 위에 게시물 > modify > 페이지 소스 보기 했을 때, value 값 잘 나오는 지 확인
@PostMapping("/remove")
public String remove(Long tno, PageRequestDTO pageRequestDTO ,RedirectAttributes redirectAttributes) {
log.info("remove()....");
log.info("tno: " + tno);
todoService.remove(tno);
redirectAttributes.addAttribute("page", 1);
redirectAttributes.addAttribute("size", pageRequestDTO.getSize());
return "redirect:/todo/list";
}
- TodoController에 위 부분 코드 변경
- 서버 재 실행 후 > 게시글 삭제하면 해당 URL로 이동
6. 검색/필터링 조건의 정의
// 검색 필터링 용도
private String[] types; // 검색 경우의 수 1) title 2) writer 3) title, writer
private String keyword; // 검색어
private boolean finished;
private LocalDate from;
private LocalDate to;
- PageRequestDTO에 link 아래에 위 코드 추가
@Test
public void testSelectSearch() {
PageRequestDTO pageRequestDTO = PageRequestDTO.builder()
.page(1)
.size(10)
.types(new String[]{"t", "w"})
.keyword("AAAA")
.build();
List<TodoVO> voList = todoMapper.selectList(pageRequestDTO);
voList.forEach(vo -> log.info(vo));
}
- TodoMapperTest에 위 코드 추가
<?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="com.example.spring_project_02.mapper.TodoMapper">
<sql id="search">
<where>
<if test="types != null and types.length > 0">
<foreach collection="types" item="type" open="(" close=")" separator=" OR">
<if test="type == 't'.toString()">
title like concat('%', #{keyword}, '%')
</if>
<if test="type =='w'.toString()">
writer like concat('%', #{keyword}, '%')
</if>
</foreach>
</if>
<if test="finished">
<trim prefix="and">
finished = 1
</trim>
<if test="from != null and to != null">
<trim prefix="and">
dueDate between #{from} and #{to}
</trim>
</if>
</if>
</where>
</sql>
<select id="getTime" resultType="string">
select now()
</select>
<insert id="insert">
INSERT INTO tbl_todo (title, dueDate, writer)
VALUES (#{title}, #{dueDate}, #{writer})
</insert>
<select id="selectAll" resultType="com.example.spring_project_02.domain.TodoVO">
select *
from tbl_todo
order by tno desc
</select>
<select id="selectOne" resultType="com.example.spring_project_02.domain.TodoVO">
select *
from tbl_todo
WHERE tno = #{tno}
</select>
<delete id="delete">
DELETE
FROM tbl_todo
WHERE tno = #{tno}
</delete>
<update id="update">
UPDATE `tbl_todo`
SET `title` = #{title},
`dueDate` = #{dueDate},
`finished` = #{finished}
WHERE `tno` = #{tno}
</update>
<select id="selectList" resultType="com.example.spring_project_02.domain.TodoVO">
select *
from tbl_todo
order by tno desc limit #{skip}, #{size}
</select>
<select id="getCount" resultType="int">
SELECT COUNT(*)
FROM tbl_todo
</select>
<select id="selectList" resultType="com.example.spring_project_02.domain.TodoVO">
select * from tbl_todo
<include refid="search"></include>
order by tno desc limit #{skip}, #{size}
</select>
<select id="getCount" resultType="int">
select count(tno) from tbl_todo
<include refid="search"></include>
</select>
</mapper>
- TodoMapper.xml에 위 코드 추가
공부 과정을 정리한 것이라 내용이 부족할 수 있습니다.
부족한 내용은 추가 자료들로 보충해주시면 좋을 것 같습니다.
읽어주셔서 감사합니다 :)