22.06.17 자유게시판
<?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.spring.myweb.freeboard.mapper.IFreeBoardMapper">
<insert id="regist">
INSERT INTO freeboard(bno, title, writer, content)
VALUES(freeboard_seq.NEXTVAL, #{title}, #{writer}, #{content})
</insert>
</mapper>
FreeBoardMapperTest
insert만 진행
<script>
package com.spring.myweb.freeboard;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/config/db-config.xml")
public class FreeBoardMapperTest {
@Autowired
private IFreeBoardMapper mapper;
@Test
public void registTest() {
for(int i=1; i<=30; i++) {
FreeBoardVO vo = new FreeBoardVO();
vo.setTitle("마이페이지 테스트" + i);
vo.setWriter("kim1234");
vo.setContent("테스트 글쓰기" + i);
mapper.regist(vo);
}
}
}
</script>
강사님이 주신 views, resources 폴더 추가
server에 MyWeb 추가
자유게시판 버튼 누르면 /freeBoard/freeList 요청이 들어감.
IFreeBoardMapper와 동일
package com.spring.myweb.freeboard.service;
public interface IFreeBoardService {
//글 등록
void regist(FreeBoardVO vo);
//글 목록
List<FreeBoardVO> getList(PageVO vo);
//총 게시물 수
int getTotal(PageVO vo);
//상세보기
FreeBoardVO getContent(int bno);
//글 수정
void update(FreeBoardVO vo);
//글 삭제
void delete(int bno);
}
검색기능,페이징 함께 구현
페이징 처리를 할수 있는 pageNum,cpp등의 값이 PageVO로 넘어온다.
PageCreator를 생성해서 현재 페이지와 총 게시물의 개수(service.getTotal(vo))를 전달하면
페이징 버튼 알고리즘 메서드가 실행된다.
목록 요청(service.getList(vo))을 보내고 boardList라는 이름으로 보낸다.
<script>
//목록 화면
@GetMapping("/freeList")
public void freeList(PageVO vo, Model model) {
System.out.println(vo);
PageCreator pc = new PageCreator();
pc.setPaging(vo);
pc.setArticleTotalCount(service.getTotal(vo));//총 게시물 개수
System.out.println(pc);
model.addAttribute("boardList", service.getList(vo));//게시물 목록
model.addAttribute("pc", pc);
}
</script>
newMark처리 함께 진행.
mapper.getList를 해서 list에서 값을 하나씩 받으면서 등록 시간을 비교해서 newMark처리 여부 판단.
<script>
@Override
public List<FreeBoardVO> getList(PageVO vo) {
List<FreeBoardVO> list = mapper.getList(vo);
//new Mark
for(FreeBoardVO article : list) {
long now = System.currentTimeMillis();//현재시간
long regTime = article.getRegDate().getTime();//등록시간
if(now - regTime < 60*60*24*2*1000) { //2일
article.setNewMark(true);
}
}
return list;
}
@Override
public int getTotal(PageVO vo) {
return mapper.getTotal(vo);
}
</script>
검색기능위해 동적 SQL 추가, 페이징 처리 함께 진행.
regdate,updatedate 는 컬럼명과 변수명이 이니셜은 같고 대소문자만 다르기 때문에
resultMap은 안써도 가능하다.
그렇기 때문에 resultType 바로 전달.
<sql id="search">
<if test="condition == 'title'">
WHERE title LIKE '%'||#{keyword}||'%'
</if>
<if test="condition == 'writer'">
WHERE writer LIKE '%'||#{keyword}||'%'
</if>
<if test="condition == 'content'">
WHERE content LIKE '%'||#{keyword}||'%'
</if>
<if test="condition == 'titleContent'">
WHERE title LIKE '%'||#{keyword}||'%'
OR content LIKE '%'||#{keyword}||'%'
</if>
</sql>
...
<select id="getList" resultType="com.spring.myweb.command.FreeBoardVO">
SELECT * FROM
(
SELECT ROWNUM AS rn, tbl.* FROM
(
SELECT * FROM freeboard
<include refid="search" />
ORDER BY bno DESC
)tbl
)
<![CDATA[
WHERE rn > (#{pageNum}-1) * #{cpp}
AND rn <= #{pageNum} * #{cpp}
]]>
</select>
<select id="getTotal" resultType="int">
SELECT COUNT(*)
FROM freeboard
<include refid="search" />
</select>
boardList로 담아온 list값 뿌리기.
regDate,updateDate도 fmt:formatDate이용해서 원하는 형식으로 변경해준다.
fmt쓰기 위해 설정도 추가.
url 주소는 makeURI메서드 이용해서 쉽게 표현.
newMark가 true면 img태그도 표시.
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
...
<c:forEach var="vo" items="${boardList}">
<tr>
<td>${vo.bno}</td>
<td>
<a href="<c:url value='/freeboard/freeDetail/${vo.bno}${pc.makeURI(pc.paging.pageNum)}' />">${vo.title}</a>
<c:if test="${vo.newMark}">
<img alt="newMark" src="<c:url value='/img/KakaoTalk_20220615_093058122.gif'/>">
</c:if>
</td>
<td>${vo.writer}</td>
<td><fmt:formatDate value="${vo.regDate}" pattern="yyyy-MM-dd HH:mm" /></td>
<td><fmt:formatDate value="${vo.updateDate}" pattern="yyyy-MM-dd HH:mm"/></td>
</tr>
</c:forEach>
사용자가 현재 위치하고 있는 페이지에 색깔을 더해주는 active클래스는 삼항조건식을 이용해 표현.
폼이용안하고 처리.
<form>
<div class="text-center">
<hr>
<ul class="pagination pagination-sm">
<c:if test="${pc.prev}">
<li><a href="<c:url value='/freeBoard/freeList${pc.makeURI(pc.beginPage-1)}'/>">이전</a></li>
</c:if>
<c:forEach var="num" begin="${pc.beginPage}" end="${pc.endPage}">
<li class="${pc.paging.pageNum == num ? 'active' : ''}"><a href="<c:url value='/freeBoard/freeList${pc.makeURI(num)}'/>">${num}</a></li>
</c:forEach>
<c:if test="${pc.next}">
<li><a href="<c:url value='/freeBoard/freeList${pc.makeURI(pc.endPage+1)}'/>">다음</a></li>
</c:if>
</ul>
<button type="button" class="btn btn-info"token tag"><c:url value="/freeBoard/freeRegist" />'">글쓰기</button>
</div>
</form>
기존에는 url같은 경우도 makeURI라는 메서드를 사용하였듯이
처리를 백엔드에서 처리했다면 이제는 프론트단에서 처리를 진행해보자.
form을 이용하기 위해 pageForm이라는 name추가하고
버튼들의 href="#", data-pagenum을 추가.
버튼 클릭 시 같이 보내줄 pageNum,cpp 등을 준비.
<!--페이지 네이션을 가져옴-->
<form action="<c:url value='/freeboard/freeList'/>" name="pageForm">
<div class="text-center">
<hr>
<ul id="pagination" class="pagination pagination-sm">
<c:if test="${pc.prev}">
<li><a href="#" data-pagenum="${pc.beginPage-1}">이전</a></li>
</c:if>
<c:forEach var="num" begin="${pc.beginPage}" end="${pc.endPage}">
<li class="${pc.paging.pageNum == num ? 'active' : ''}"><a href="#" data-pagenum="${num}">${num}</a></li>
</c:forEach>
<c:if test="${pc.next}">
<li><a href="#" data-pagenum="${pc.endPage+1}">다음</a></li>
</c:if>
</ul>
<button type="button" class="btn btn-info"token tag"><c:url value="/freeBoard/freeRegist" />'">글쓰기</button>
</div>
<!-- 페이지 관련 버튼(이전,다음,페이지번호)을 클릭 시 같이 숨겨서 보내줄 공통 값 -->
<input type="hidden" name="pageNum" value="${pc.paging.pageNum}">
<input type="hidden" name="cpp" value="${pc.paging.cpp}">
<input type="hidden" name="condition" value="${pc.paging.condition}">
<input type="hidden" name="keyword" value="${pc.paging.keyword}">
</form>
사용자가 페이지 관련 버튼을 클랙했을 때, 기존에는 각각의 a태그를 href에다가
각각 다른 url을 작성해서 요청을 보내줬다면,
이번에는 클릭한 그 버튼이 무엇인지를 확인해서
그 버튼에 맞는 페이지 정보를 자바스크립트로 끌고와서 요청을 보내 주겠다.
<script>
$(function() {
$('#pagination').on('click', 'a', function(e) {
e.preventDefault(); //a태그의 고유기능 중지.
//현재 이벤트가 발생한 요소(버튼)의
//data-pageNum의 값을 얻어서 변수에 저장.
//const value = e.target.dataset.pagenum; -> Vanilla JS
const value = $(this).data('pagenum'); // -> jQuery
//페이지 버튼들을 감싸고 있는 form태그를 name으로 지목하여
//그 안에 숨겨져 있는 pageNum이라는 input태그의 value에
//위에서 얻은 data-pageNum의 값을 삽입 한 후 submit
document.pageForm.pageNum.value = value;
document.pageForm.submit();
});
}); //end jQuery
</script>
폼이용 안하고 자바스크립트로 처리해 보기.
<form>
<div class="search-wrap">
<button type="button" class="btn btn-info search-btn">검색</button>
<input type="text" name="keyword" class="form-control search-input" value="${pc.paging.keyword}">
<select class="form-control search-select" name="condition">
<option value="title" ${pc.paging.condition == 'title' ? 'selected' : ''}>제목</option>
<option value="content" ${pc.paging.condition == 'content' ? 'selected' : ''}>내용</option>
<option value="writer" ${pc.paging.condition == 'writer' ? 'selected' : ''}>작성자</option>
<option value="titleContent" ${pc.paging.condition == 'titleContent' ? 'selected' : ''}>제목+내용</option>
</select>
</div>
</form>
JQeury
{pageContext.request.contextPath}는
<c:url value=""/>와 같은 문법.
keyword, condition의 입력값을 받아와서 url에 함께 전달.
<script>
$(function() {
$('.search-btn').click(function() {
const keyword = $('.search-input').val();
const condition = $('.search-select').val();
location.href='${pageContext.request.contextPath}/freeboard/freeList?keyword=' + keyword + '&condition=' + condition;
});
}); //end jQuery
</script>
검색도 폼 이용해서 보내버림
<!--form select를 가져온다 -->
<form action="<c:url value='/freeboard/freeList' />">
<div class="search-wrap">
<button type="submit" class="btn btn-info search-btn">검색</button>
<input type="text" name="keyword" class="form-control search-input" value="${pc.paging.keyword}">
<select class="form-control search-select" name="condition">
<option value="title" ${pc.paging.condition == 'title' ? 'selected' : ''}>제목</option>
<option value="content" ${pc.paging.condition == 'content' ? 'selected' : ''}>내용</option>
<option value="writer" ${pc.paging.condition == 'writer' ? 'selected' : ''}>작성자</option>
<option value="titleContent" ${pc.paging.condition == 'titleContent' ? 'selected' : ''}>제목+내용</option>
</select>
</div>
</form>