★ 결과
★ 사전설정
- 개발환경: 'pom.xml' → spring framework 버전 - 5.3.19
2022.08.02 - [백엔드 보고/스프링 (Spring)] - 프로젝트 개발 기준
프로젝트 개발 기준
앞으로 올리는 보물들은 아래 기준으로 업데이트 할 예정입니다. 참고해주세용!! * Windows 10 Pro (64Bit 운영체제) * 전자정부 프레임워크 (링크: https://www.egovframe.go.kr/) - 표준프레임워크 개발자 교.
bogoitsaw.tistory.com
- My-SQL 셋팅: mysql 프로그램이 활성화되어있는 상태. (참고자료)
2022.08.04 - [백엔드 보고/My SQL (DB)] - My-SQL 셋팅
My-SQL 셋팅
처음 설치한다 가정하구, 접속하는것부터 시작해볼게용!~ ★ 사전설정 2022.08.02 - [백엔드 보고/스프링 (Spring)] - 프로젝트 개발 기준 ★ My-SQL 접속하기 mysql 접속하기 위해 cmd창을 띄워봅시닷! cmd
bogoitsaw.tistory.com
- Spring과 DB연동 상태: Controller, Mapper, Domain.. 등 모두 셋팅되어있어야합니다.
2022.08.05 - [백엔드 보고/My SQL (DB)] - Spring과 DB 연동
Spring과 DB 연동
★ 결과 실제 서비스에서 많이 쓰는 쿼리문들로 구성해놓은 틀을 공개합니다! ^.^// My-sql과 연동 및 유지보수를 위해 'Hikari-CP', 'MyBatis', Lombok'을 이용하였습니다. ★ 사전설정 개발환경: 'pom.xml..
bogoitsaw.tistory.com
- 게시판 다루기: 게시판이 구현되어있는 상황이어야 합니다. '게시판다루기'먼저 하신 후에 이 포스팅 따라하시길 권장합니다.
2022.08.07 - [백엔드 보고/스프링 (Spring)] - 게시판 다루기
게시판 다루기
★ 결과 ■ 게시판 자세히보기 ■ 게시판 생성하기 ■ 게시판 수정하기 ■ 게시판 삭제하기 ★ 사전설정 - 개발환경: 'pom.xml' → spring framework 버전 - 5.3.19 2022.08.02 - [백엔드 보고/..
bogoitsaw.tistory.com
★ 준비물
* jar파일 위치
/webapp/WEB-INF/lib/PageObject.jar
* tag파일 위치
/webapp/WEB-INF/tags/pageNav.tag
아래 링크에서 파일을 다운받아, 일부 알고리즘부분을 수정하여 위에 파일을 올렸습니다.
어느것을 수정하였는지는, 아래 더보기를 확인하면 알 수 있습니다.
- 다음 페이지가 있어도 다음버튼을 누를 수 없는 버그 수정 (pageNav.tag 수정)
(1페이지라고 가정할 시)


2. 가장 최신 글부터 순서대로 출력할 수 있도록 수정 (pageObejct.jar 의 setTotalRaw 알고리즘 수정)
- 아래는 TMI라 생략해두됩니닷
pageObject.jar 수정법)





만든 jar파일을 본 Project의 lib폴더안에 넣어주시면 됩니다.
파일 출처: https://cafe.naver.com/webjjangma/6787
[2021.06.01] JSP & Servlet - 페이지 처리 : PageObject 라이브러리
* 라이브러리 위치 /webapp/WEB-INF/lib/PageObject.jar * tag의 위치 /webapp/WEB-INF/tags/pageNav.tag -------...
cafe.naver.com
★ DB 생성
DB는 게시판 다루기에서 만들었던DB 그대로 활용합니다.
(DB를 어떻게 넣는지 모르겠다면, ★사전설정에 My-SQL 셋팅을 참고해주세요)
★ 틀
■ pom.xml (아래 시작하기 전에, 반드시 이거먼저 복붙 해주세요)
※ 유지보수를 위해, 필요한 내용만 빼서 올립니다.
(Mybatis, Hikari CP...등 pom.xml에 들어가있는 상태이이니, 아직 안넣으신분은, spring과 DB연동 참고해주세요.)
- 넣을 내용
<!-- 페이지처리 -->
<dependency>
<groupId>com.webjjang</groupId>
<artifactId>util.PageObject</artifactId>
<version>2.5</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/pageObject.jar</systemPath>
</dependency>
- 넣을 위치
■ Domain / Testboard.java ('게시판 다루기' 포스팅과 동일합니다.)
package com.test.Domain;
import lombok.Data;
@Data
public class Testboard {
private int b_seq;
private String b_title;
private String b_writer;
private String b_content;
private String b_regdate;
private String b_img;
}
■ Mapper / TestMapper.java
public List<Testboard> selectAllBoard(PageObject pageObject) throws Exception;
public int getTotalTestRow(PageObject pageObject) throws Exception;
- 넣을 위치 (노란색 영역)
※ 기존에 있던 selectAllBoard를 위의 내용 복사해서 붙여넣어주어 바꿔주시면 됩니다. (다음 아래도 위와동일한 방법으로 바꿔주시면 됩니다.)
■ Mapper / TestMapper.xml
<select id = "selectAllBoard" parameterType = "com.webjjang.util.PageObject" resultType = "com.test.Domain.Testboard">
SELECT *
FROM (
SELECT
@rownum:=@rownum+1 rnum,
t.*
FROM
testboard t,
(SELECT @ROWNUM := 0) R
WHERE ( 1 = 1 )
) list
WHERE rnum <![CDATA[>=]]> #{startRow} AND rnum <![CDATA[<=]]> #{endRow} order by b_seq DESC
</select>
<select id="getTotalTestRow" resultType="int" parameterType = "com.webjjang.util.PageObject">
SELECT count(*) from testboard
</select>
- 넣을 위치(노란색 영역)
Tip) 게시글이 먼저 만들어진 순서대로 출력되게 만들고 싶은 분들의 팁
<select id = "selectAllBoard" parameterType = "com.webjjang.util.PageObject" resultType = "com.test.Domain.Testboard">
SELECT *
FROM (
SELECT
@rownum:=@rownum+1 rnum,
t.*
FROM
testboard t,
(SELECT @ROWNUM := 0) R
WHERE ( 1 = 1 )
<include refid="noticeSearch"/>
) list
WHERE rnum <![CDATA[>=]]> #{startRow} AND rnum <![CDATA[<=]]> #{endRow} order by b_seq DESC
</select>
sql문 가장 뒤쪽에 '...order by b_seq DESC ' 라고 적혀져있는데, 여기서 'b_seq' 이부분을 예를들어 'b_regdate'로 바꾼다면, 가장 최근에 만들어진거부터 순서대로 출력이 되겠지요?
■ Service / TestService.java
public List<Testboard> selectAllBoard(PageObject pageObject) throws Exception{
pageObject.setTotalRow(Integer.parseInt(String.valueOf(mapper.getTotalTestRow(pageObject))));
return mapper.selectAllBoard(pageObject);
}
- 넣을 위치(노란색 영역)
■ Controller / HomeController.java (그대로 복붙하시면 됩니다.)
package com.test.Controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.test.Domain.Testboard;
import com.test.Service.TestService;
import com.webjjang.util.PageObject;
/**
* Handles requests for the application home page.
*/
@Controller
public class HomeController {
@Autowired
private TestService service;
@RequestMapping(value = {"/","/main","/home"}, method = RequestMethod.GET)
public String home(@ModelAttribute PageObject pageObject, Model model) throws Exception {
if (pageObject.getPerPageNum() == 10) {
pageObject.setPerPageNum(12); //12개 출력하고 싶을 때setPerPageNum안에 12를 적어넣어주세요.
pageObject.setPerGroupPageNum(12); //12개 출력하고 싶을 때setPerGroupPageNum안에 12를 적어넣어주세요.
} //다른 숫자도 가능합니다.
List<Testboard> selectAllBoard = service.selectAllBoard(pageObject);
if (pageObject.getPage() < 1)
pageObject.setPage(1);
model.addAttribute("test", selectAllBoard);
return "home";
}
@RequestMapping("/view")
public String view(@ModelAttribute PageObject pageObject, int b_seq, Model model) {
Testboard tb = service.selectSeqBoard(b_seq);
model.addAttribute("test", tb);
return "view";
}
@RequestMapping("/write")
public String write() {
return "write";
}
@RequestMapping("/write.do")
public String writedo(Testboard tb, int perPageNum) {
service.insertBoard(tb);
return "redirect:main?perPageNum="+perPageNum;
}
@RequestMapping("/update")
public String update(int b_seq, Model model) {
Testboard tb = service.selectSeqBoard(b_seq);
model.addAttribute("test", tb);
return "update";
}
@RequestMapping("/update.do")
public String updatedo(Testboard tb, PageObject pageObject) {
service.updateBoard(tb);
return "redirect:main?page="+pageObject.getPage() + "&perPageNum=" + pageObject.getPerPageNum();
}
@RequestMapping("/delete.do")
public String deletedo(int b_seq, int perPageNum) {
service.deleteBoard(b_seq);
return "redirect:main?perPageNum="+perPageNum;
}
}
- 한페이지에 출력하고 싶은 양은 여기에서 조절가능합니다. home메소드 안에서, pageObject의 setPerPageNum와 setPerGroupPageNum에 원하는 페이지의 양을 동일하게 적어넣어주세요.
* 바꿔준 부분
- home
-> pageObject부분들을 추가해주었습니다.
- writedo, updatedo, deletedo
-> 각 return에 get방식으로 출력하는 부분들 수정해주었습니다.
■ views / home.jsp (다음 jsp부분들은 그대로 복붙하시면됩니다.)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="pageObject" tagdir="/WEB-INF/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판 리스트</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<!-- css - 꾸미기 -->
<style type="text/css">
.dataRow:hover {
background: #eee;
cursor: pointer;
}
div.nav-align{
text-align: center;
}
</style>
<script type="text/javascript">
$(function(){
$(".dataRow").click(function(){
var b_seq = $(this).find(".b_seq").text();
location = "view?b_seq=" + b_seq + "&page=" + "${pageObject.page}" + "&perPageNum=" + "${pageObject.perPageNum}";
});
$("#perPageNumSelect").change(function () {
$("#perPageNumForm").submit();
});
});
</script>
</head>
<body>
<div class="container">
<h1>게시판 리스트</h1>
<form action="main" class="form-inline" id="perPageNumForm">
<input name="page" type="hidden" value="1">
<select name="perPageNum" class="form-control" id="perPageNumSelect">
<option ${(pageObject.perPageNum==3)?"selected":"" }>3</option>
<option ${(pageObject.perPageNum==6)?"selected":"" }>6</option>
<option ${(pageObject.perPageNum==9)?"selected":"" }>9</option>
<option ${(pageObject.perPageNum==12)?"selected":"" }>12</option>
<option ${(pageObject.perPageNum==15)?"selected":"" }>15</option>
</select>
</form>
<table class="table">
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
</tr>
<c:if test="${empty test }">
<tr>
<td colspan="3">데이터가 존재하지 않습니다.</td>
</tr>
</c:if>
<c:if test="${!empty test }">
<c:forEach items="${requestScope.test }" var="vo">
<tr class="dataRow">
<td class="b_seq" >${pageScope.vo.b_seq }</td>
<td >${vo.b_title }</td>
<td >${vo.b_writer }</td>
</tr>
</c:forEach>
</c:if>
</table>
<a href = "write?perPageNum=${pageObject.perPageNum }" class="btn btn-default">글쓰기</a>
<!-- 페이지네이션 -->
<div class = "nav-align">
<pageObject:pageNav listURI="main" pageObject="${pageObject }" />
</div>
</div>
</body>
</html>
※ pageObject와 한 페이지당 고르는 수 추가.
Tip) 이식할 때 참고사항 (좀 더 유연하게 사용하고 싶은분들은 더보기눌러주세용)
◆ option 태그 안에있는 perPageNum부분의 숫자는 한 페이지 당 보고싶은 숫자들을 적어둔거에요. option 태그를 삭제하든, 자신이 원하는 한페이지에 출력하는 양을 설정하든 맘대로 적어주시면됩니다.
<select name="perPageNum" class="form-control" id="perPageNumSelect">
<option ${(pageObject.perPageNum==3)?"selected":"" }>3</option>
<option ${(pageObject.perPageNum==6)?"selected":"" }>6</option>
<option ${(pageObject.perPageNum==9)?"selected":"" }>9</option>
<option ${(pageObject.perPageNum==12)?"selected":"" }>12</option>
<option ${(pageObject.perPageNum==15)?"selected":"" }>15</option>
</select>
◆ listURI 부분의 "main"은 pageObject를 사용하고 있는 이 jsp 이름을 적어주시면됩니다. 이건 jsp마다 달라요~
<div class = "nav-align">
<pageObject:pageNav listURI="main" pageObject="${pageObject }" />
</div>
■ views / view.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="pageObject" tagdir="/WEB-INF/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판 자세히보기</title>
<!-- BootStrap 라이브러리 등록 -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(function(){
$(".deleteBtn").click(function(){
return confirm("정말 삭제하시겠습니까?");
});
});
</script>
</head>
<body>
<div class="container">
<h1>게시판 자세히보기</h1>
<table class="table">
<tr>
<td colspan="5">
<a href="update?b_seq=${test.b_seq }" class="btn btn-default">수정</a>
<a href="delete.do?b_seq=${test.b_seq }" class="btn btn-default deleteBtn">삭제</a>
<a href="main?page=${pageObject.page }&perPageNum=${pageObject.perPageNum}" class="btn btn-default">홈</a>
</td>
</tr>
<tr>
<th style="width: 100px;">번호</th>
<td>${test.b_seq }</td>
</tr>
<tr>
<th>제목</th>
<td>${test.b_title }</td>
</tr>
<tr>
<th>내용</th>
<td>${test.b_content }</td>
</tr>
<tr>
<th>작성자</th>
<td>${test.b_writer }</td>
</tr>
<tr>
<th>작성일</th>
<td>
<fmt:parseDate value="${test.b_regdate}" var="dateFmt" pattern="yyyy-MM-dd HH:mm:ss"/>
<fmt:formatDate value="${dateFmt}" pattern="yyyy-MM-dd HH:mm:ss" />
</td>
</tr>
<tr>
<td colspan="5">
<a href="update?b_seq=${test.b_seq }" class="btn btn-default">수정</a>
<a href="delete.do?b_seq=${test.b_seq }" class="btn btn-default deleteBtn">삭제</a>
<a href="main?page=${pageObject.page }&perPageNum=${pageObject.perPageNum}" class="btn btn-default">홈</a>
</td>
</tr>
</table>
</div>
</body>
</html>
Tip) 날짜 포맷팅, formatDate
-> parseDate
- value: 바꿔줄 변수 셋팅
- var: 쓰일 변수
- pattern: 바꿔줄 변수의 패턴 (위의 예시는 yyyy-MM-dd HH:mm:ss 형태로 출력됨을 컴퓨터에게 알려주고있음.)
-> formatDate
- value: 날짜형식을 바꿔줄 변수 셋팅
- pattern: 바꿔줄 형식
※형식에 관하여서 더 자세히 보고싶다면 '더보기'를 눌러 표를 참고
자주 쓰일것들만 모았습니다.
Format | Description | |
%a | Abbreviated weekday name (Sun to Sat) | 요일 명 출력(ex - Sun, Sat) |
%b | Abbreviated month name (Jan to Dec) | 월 별 이름 출력(ex - Jan, Dec) |
%c | Numeric month name (0 to 12) | 월 별 이름 출력(ex - 1, 12) |
%D | Day of the month as a numeric value, followed by suffix (1st, 2nd, 3rd, ...) | 일 이름을 1st, 2nd,... 으로 |
%k | Hour (0 to 23) | 24시간 표기법으로 |
%l | Hour (1 to 12) | 12시간 표기법으로 |
%M | Month name in full (January to December) | 월 별 이름을 Full Name으로 출력 (ex - January, December) |
%m | Month name as a numeric value (00 to 12) | 월 별 이름을 0으로 매꿔서 출력 (ex - 01, 09, 12) |
%p | AM or PM | PM, AM 표시 |
%T | Time in 24 hour format (hh:mm:ss) | 24시간 표기법으로, 0으로 매꿔서 (시:분:초) (ex- 23:15:15) |
%W | Weekday name in full (Sunday to Saturday) | 요일 명을 Full Name으로 출력 (ex - Friday, Sunday, Saturday) |
%w | Day of the week where Sunday=0 and Saturday=6 | 요일을 숫자로 표현 (ex - Sunday=0, Saturday=6) |
%X | Year for the week where Sunday is the first day of the week. Used with %V | 일주일의 시작을 일요일 |
%x | Year for the week where Monday is the first day of the week. Used with %v | 일주일의 시작을 월요일 |
%Y | Year as a numeric, 4-digit value | 년도를 4자리로 출력 |
%y | Year as a numeric, 2-digit value | 년도를 2자리로 출력 (ex - '2017'은 '17', '2000'은 '00') |
더 많은 것을 보고싶다면 아래 '참고자료' 참고
- 참고자료
https://www.w3schools.com/mysql/func_mysql_date_format.asp
MySQL DATE_FORMAT() Function
W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.
www.w3schools.com
■ views / write.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="pageObject" tagdir="/WEB-INF/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판 글쓰기</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(function () {
$(".cancelBackBtn").click(function () {
history.back();
});
});
</script>
</head>
<body>
<div class="container">
<h1>게시판 글쓰기 폼</h1>
<form action="write.do" method="post">
<input name="perPageNum" type="hidden" value="${param.perPageNum }">
<div class="form-group">
<label for="title">제목:</label>
<input name="b_title" type="text" class="form-control" id="title"maxlength="100">
</div>
<div class="form-group">
<label for="content">내용:</label>
<textarea name="b_content" class="form-control" rows="5"
id="content"></textarea>
</div>
<div class="form-group">
<label for="writer">작성자:</label>
<input name="b_writer" type="text" class="form-control" id="writer" maxlength="20">
</div>
<button>등록</button>
<button type="button" class="cancelBackBtn">취소</button>
</form>
</div>
</body>
</html>
■ views / update.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="pageObject" tagdir="/WEB-INF/tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판 글수정</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(function () {
$(".cancelBackBtn").click(function () {
history.back();
});
});
</script>
</head>
<body>
<div class="container">
<h1>게시판 글수정 폼</h1>
<form action="update.do" method="post">
<input name="page" type="hidden" value="${param.page }" />
<input name="perPageNum" type="hidden" value="${param.perPageNum }" />
<div class="form-group">
<label for="b_seq">번호:</label>
<input name="b_seq" type="text" class="form-control" id="b_seq" value="${test.b_seq }" readonly="readonly">
</div>
<div class="form-group">
<label for="title">제목:</label>
<input name="b_title" type="text" class="form-control" id="title" maxlength="100"
required="required" value="${test.b_title }">
</div>
<div class="form-group">
<label for="content">내용:</label>
<textarea name="b_content" class="form-control" rows="5" id="content">${test.b_content }</textarea>
</div>
<div class="form-group">
<label for="writer">작성자:</label>
<input name="b_writer" type="text" class="form-control" id="writer" maxlength="20" value="${test.b_writer }" readonly="readonly">
</div>
<div class="form-group">
<label for="b_regdate">작성일:</label>
<input name="b_regdate" type="text" class="form-control" id="b_regdate" maxlength="20" value="${test.b_regdate }" readonly="readonly">
</div>
<button>수정</button>
<button type="button" class="cancelBackBtn">취소</button>
</form>
</div>
</body>
</html>
- 각 jsp마다 page와 perPageNum을 기억할 수 있도록 hidden으로 숨겨두어서, '취소', '홈'버튼을 누를 시에도 페이지가 유지될거에용!
Tip) 페이지 번호부분을 수정하고 싶을 경우엔, pageNav.tag를 수정하시면 됩니다~! 가령 화살표를 없애고싶을 경우엔, 해당하는 화살표태그를 삭제하시면됩니닷!
필요하신 분들을 위해, 프로젝트 자체를 압축해서 이곳에 올릴게용.
'백엔드 보고 > 스프링 (Spring)' 카테고리의 다른 글
이미지 게시판 (0) | 2022.08.09 |
---|---|
검색 기능 (0) | 2022.08.08 |
게시판 다루기 (0) | 2022.08.07 |
프로젝트 개발 기준 (0) | 2022.08.02 |