Spring MyWeb Board

정원·2022년 6월 17일

Spring-MyWeb

목록 보기
2/16

22.06.17 자유게시판

FreeBoardMapper 생성

<?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>

test 진행

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 요청이 들어감.

IFreeBoardService

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);
}

게시물 목록("/freeList")

검색기능,페이징 함께 구현

FreeBoardController

페이징 처리를 할수 있는 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>

FreeBoardService

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>

FreeBoardMapper

검색기능위해 동적 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>

freeLsit.jsp

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>
		&nbsp;&nbsp;&nbsp;
        <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>

검색

freeLsit.jsp

폼이용 안하고 자바스크립트로 처리해 보기.

<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>

0개의 댓글