데일리로그C:
article thumbnail

넘버링

1. listPage.jsp --> 추가

<bash />
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ include file="/WEB-INF/views/include/header.jsp" %> <script> var result = "${msg}"; if(result == "register"){ // alert 뜬 후 새로고침하면 없어지므로 다시 뜨진 않음 alert("작성 완료!"); }else if(result == "delete"){ alert("삭제 완료!"); }else if(result == "modify"){ alert("수정 완료!"); } </script> <center> <h3>LIST PAGE</h3> <table border=1 width=700> <tr> <th style="width:10px">BNO</th> <th>TITLE</th> <th>WRITER</th> <th>REGDATE</th> <th style="width: 40px">VIEWCNT</th> </tr> <c:set var="number" value="${pageMaker.totalCount - (pageMaker.cri.page - 1) * pageMaker.cri.perPageNum }" /> <c:forEach var="boardVO" items="${list}"> <tr> <td>${number}</td> <td> <!-- pageMaker.cri.page or cri.page --> <%-- <a href="/board/readPage?bno=${boardVO.bno }&page=${pageMaker.cri.page}">${boardVO.title }</a> --%> <a href="/board/readPage${pageMaker.makeQuery(pageMaker.cri.page)}&bno=${boardVO.bno }">${boardVO.title }</a> <!-- UriComponentsBuilder 이용한다면 --> </td> <td>${boardVO.writer }</td> <!-- <td>${boardVO.regdate }</td> --> <td><fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss" value="${boardVO.regdate }"/></td> <td>${boardVO.viewcnt }</td> </tr> <c:set var="number" value="${number - 1 }"/> </c:forEach> </table> <br> <table border=0 width=700> <tr> <td align=right><a href="register">[글쓰기]</a></td> </tr> </table> <!-- 페이징 추가 --> <table border=1 align=center> <tr> <c:if test="${pageMaker.prev}"> <td> <%-- <a href="listPage?page=${pageMaker.startPage - 1 }">&laquo;</a> --%> <a href="listPage${pageMaker.makeQuery(pageMaker.startPage - 1)}">&laquo;</a> </td> </c:if> <c:forEach var="idx" begin="${pageMaker.startPage }" end="${pageMaker.endPage }"> <td> <c:if test="${pageMaker.cri.page == idx}"><b></c:if> <a href="listPage${pageMaker.makeQuery(idx)}">${idx}</a> <!-- <a href="listPage?page=${idx}">${idx}</a> --> <c:if test="${pageMaker.cri.page == idx}"></b></c:if> </td> </c:forEach> <c:if test="${pageMaker.next && pageMaker.endPage > 0}"> <td> <%-- <a href="listPage?page=${pageMaker.endPage +1 }">&raquo;</a> --%> <a href="listPage${pageMaker.makeQuery(pageMaker.endPage +1)}">&raquo;</a> </td> </c:if> </tr> </table> </center> <%@ include file="/WEB-INF/views/include/footer.jsp" %>

 

조회수

1. boardMapper.xml --> 추가

<bash />
<update id="updateViewCnt"> update tbl_board set viewcnt = viewcnt + 1 where bno = #{bno} </update>

 

2. BoardDAOImpl.java --> 추가

<bash />
@Override public BoardVO read(Integer bno) throws Exception { // 있다면 session.update(namespace+".updateViewCnt", bno); // 조회수 올린 다음 return session.selectOne(namespace+".read", bno); // 한건의 데이터 보여주기 }

 

 

검색

사용자가 게시물을 검색을 하고 난 후, 목록 페이지를 만들려면 적어도 다음과 같은 정보가 필요
 ㄴ> page(현재페이지의 번호)
 ㄴ> perPageNum(페이지당 보여지는 데이터의 수)
 ㄴ> searchType(field)
 ㄴ> keyword
 

1. SearchCriteria.java

<bash />
package org.zerock.domain; import lombok.Data; @Data public class SearchCriteria extends Criteria { // 상속(Cri 대신 사용하면 됨) private String searchType; private String keyword; }

 

2. SearchBoardController.java

<bash />
package org.zerock.controller; import javax.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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 org.zerock.domain.PageMaker; import org.zerock.domain.SearchCriteria; import org.zerock.service.BoardService; @Controller @RequestMapping("/sboard/*") // 부모 public class SearchBoardController { private static final Logger logger = LoggerFactory.getLogger(SearchBoardController.class); @Inject private BoardService service; //인스턴스 변수의 선언으로 BoardService 객체를 주입 받을 수 있게 설계 처리 //@ModelAttribute("cri")를 사용함으로써 cri객체를 list.jsp에 자동 전달 처리된다. @RequestMapping(value = "/list", method = RequestMethod.GET) public void list(@ModelAttribute("cri") SearchCriteria cri, Model model) throws Exception { logger.info(cri.toString()); model.addAttribute("list", service.listCriteria(cri)); PageMaker pageMaker = new PageMaker(); pageMaker.setCri(cri); pageMaker.setTotalCount(service.listCountCriteria(cri)); model.addAttribute("pageMaker", pageMaker); //위 @ModelAttribute("cri") 생략 한다면 아래 구문을 추가해 준다. //model.addAttribute("cri", cri); } }

 

3. PageMaker.java --> 추가

<bash />
// search 추가 public String makeSearch(int page) { UriComponents uriComponents = UriComponentsBuilder.newInstance() .queryParam("page", page) .queryParam("perPageNum", cri.getPerPageNum()) .queryParam("searchType", ((SearchCriteria) cri).getSearchType()) .queryParam("keyword", ((SearchCriteria) cri).getKeyword()) //.queryParam("keyword", encoding(((SearchCriteria) cri).getKeyword())) //한글이 깨진다면 사용 .build(); return uriComponents.toUriString(); }

 

4. sboard 폴더 생성 --> views 에

 

5. sboard/list.jsp

<bash />
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ include file="/WEB-INF/views/include/header.jsp" %> <script> var result = "${msg}"; if(result == "register"){ // alert 뜬 후 새로고침하면 없어지므로 다시 뜨진 않음 alert("작성 완료!"); }else if(result == "delete"){ alert("삭제 완료!"); }else if(result == "modify"){ alert("수정 완료!"); } </script> <script> function change(ppn){ /* location.href="list?page=1&perPageNum="+ppn; */ location.href="list?page=1&perPageNum="+ppn+"&searchType=${cri.searchType}&keyword=${cri.keyword}"; } </script> <center> <h3>LIST PAGE</h3> <table border=0 width=700> <tr> <td> Total : ${pageMaker.totalCount } <!-- pageMaker가 가지고 있으므로 --> <select name="perPageNum" onchange="change(this.value)"> <option value="1" <c:if test="${pageMaker.cri.perPageNum == 1}">selected</c:if>>1개</option> <option value="2" <c:if test="${pageMaker.cri.perPageNum == 2}">selected</c:if>>2개</option> <option value="4" <c:if test="${pageMaker.cri.perPageNum == 4}">selected</c:if>>4개</option> <option value="5" <c:if test="${pageMaker.cri.perPageNum == 5}">selected</c:if>>5개</option> <option value="10" <c:if test="${pageMaker.cri.perPageNum == 10}">selected</c:if>>10개</option> </select> </td> <td align=right> <!-- search 시작 --> <form method="get"> <input type="hidden" name="perPageNum" value="${pageMaker.cri.perPageNum}"> <select name="searchType"> <option value="n" ${cri.searchType == null?'selected':''}>---</option> <option value="t" ${cri.searchType eq 't'?'selected':''}>Title</option> <option value="c" ${cri.searchType eq 'c'?'selected':''}>Content</option> <option value="w" ${cri.searchType eq 'w'?'selected':''}>Writer</option> <option value="tc" ${cri.searchType eq 'tc'?'selected':''}>Title OR Content</option> <option value="cw" ${cri.searchType eq 'cw'?'selected':''}>Content OR Writer</option> <option value="tcw" ${cri.searchType eq 'tcw'?'selected':''}>Title OR Content OR Writer</option> </select> <input type="text" name='keyword' id="keywordInput" value='${cri.keyword }'> <input type="submit" value="Search"> </form> <!-- search 끝 --> </td> </tr> </table> <table border=1 width=700> <tr> <th style="width:10px">BNO</th> <th>TITLE</th> <th>WRITER</th> <th>REGDATE</th> <th style="width: 40px">VIEWCNT</th> </tr> <c:set var="number" value="${pageMaker.totalCount - (pageMaker.cri.page - 1) * pageMaker.cri.perPageNum }" /> <c:forEach var="boardVO" items="${list}"> <tr> <td>${number}</td> <td> <!-- pageMaker.cri.page or cri.page --> <%-- <a href="/board/readPage?bno=${boardVO.bno }&page=${pageMaker.cri.page}">${boardVO.title }</a> --%> <a href="read${pageMaker.makeSearch(pageMaker.cri.page)}&bno=${boardVO.bno }">${boardVO.title }</a> <!-- UriComponentsBuilder 이용한다면 --> </td> <td>${boardVO.writer }</td> <!-- <td>${boardVO.regdate }</td> --> <td><fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss" value="${boardVO.regdate }"/></td> <td>${boardVO.viewcnt }</td> </tr> <c:set var="number" value="${number - 1 }"/> </c:forEach> </table> <br> <table border=0 width=700> <tr> <td align=right><a href="register${pageMaker.makeQuery(pageMaker.cri.page)}">[글쓰기]</a></td> </tr> </table> <!-- 페이징 추가 --> <table border=1 align=center> <tr> <c:if test="${pageMaker.prev}"> <td> <%-- <a href="listPage?page=${pageMaker.startPage - 1 }">&laquo;</a> --%> <a href="list${pageMaker.makeSearch(pageMaker.startPage - 1)}">&laquo;</a> </td> </c:if> <c:forEach var="idx" begin="${pageMaker.startPage }" end="${pageMaker.endPage }"> <td> <c:if test="${pageMaker.cri.page == idx}"><b></c:if> <a href="list${pageMaker.makeSearch(idx)}">${idx}</a> <!-- <a href="listPage?page=${idx}">${idx}</a> --> <c:if test="${pageMaker.cri.page == idx}"></b></c:if> </td> </c:forEach> <c:if test="${pageMaker.next && pageMaker.endPage > 0}"> <td> <%-- <a href="listPage?page=${pageMaker.endPage +1 }">&raquo;</a> --%> <a href="list${pageMaker.makeSearch(pageMaker.endPage +1)}">&raquo;</a> </td> </c:if> </tr> </table> </center> <%@ include file="/WEB-INF/views/include/footer.jsp" %>

 

6. header.jsp --> 추가

<bash />
<a href="/sboard/list">[listSearch]</a>

 

7. BoardDAO.java --> 추가

<bash />
public List<BoardVO> listSearch(SearchCriteria cri) throws Exception; public int listSearchCount(SearchCriteria cri) throws Exception;

 

8. BoardDAOImpl.java --> 추가

<bash />
@Override // 검색 public List<BoardVO> listSearch(SearchCriteria cri) throws Exception { return session.selectList(namespace+".listSearch", cri); } @Override public int listSearchCount(SearchCriteria cri) throws Exception { return session.selectOne(namespace+".listSearchCount", cri); }

 

9. boardMapper.xml --> 추가

<bash />
<!-- search --> <select id="listSearch" resultType="BoardVO"> <![CDATA[ select * from tbl_board where bno > 0 ]]> <include refid="search"></include> <![CDATA[ order by bno desc, regdate desc limit #{pageStart}, #{perPageNum} ]]> </select> <select id="listSearchCount" resultType="int"> <![CDATA[ select count(bno) from tbl_board where bno > 0 ]]> <include refid="search"></include> </select> <sql id="search"> <if test="searchType != null" > <!-- MyBatis에서는 변수가 자바객체처럼 사용되므로 ( OGNL (Object Graph Navigation Language)를 사용하여 속성 처리를 하고 있기 때문에 ) 자바에서 사용되는 문자열 비교 메소드를 이용하면 된다. 단 비교할 문자를 먼저 쓴 경우도 에러 발생. <if test="searchType == 't'.toString()"> (o) <if test="searchType eq 't'.toString()"> (o) <if test="searchType.toString() == 't'.toString()"> (o) <if test="searchType.equalsIgnoreCase('t')"> (o) <if test='searchType == "t"'> (o) // 작은, 큰 따옴표 순서 <if test='"t".equals(searchType)'> (o) toString() 사용안하는 경우에 <if test="'t'.equals(searchType)"> (x) <if test='searchType.equals("t")'> (o) <if test="searchType.equals('t')"> (x) --> <!-- CONCAT 함수 필수(like 비교를 위해서) --> <if test="searchType == 't'.toString()"> <!-- title이라면 --> and title like CONCAT('%', #{keyword}, '%') </if> <if test="searchType == 'c'.toString()"> <!-- content라면 --> and content like CONCAT('%', #{keyword}, '%') </if> <if test="searchType == 'w'.toString()"> <!-- writer이라면 --> and writer like CONCAT('%', #{keyword}, '%') </if> <if test="searchType == 'tc'.toString()"> <!-- title, content라면 --> and ( title like CONCAT('%', #{keyword}, '%') OR content like CONCAT('%', #{keyword}, '%')) </if> <if test="searchType == 'cw'.toString()"> <!-- content, writer이라면 --> and ( content like CONCAT('%', #{keyword}, '%') OR writer like CONCAT('%', #{keyword}, '%')) </if> <if test="searchType == 'tcw'.toString()"> <!-- title, content, writer이라면 --> and ( title like CONCAT('%', #{keyword}, '%') OR content like CONCAT('%', #{keyword}, '%') OR writer like CONCAT('%', #{keyword}, '%')) </if> </if> </sql>

 

10. BoardDAOTest.java

<bash />
//@Test public void testDynamic1() throws Exception { SearchCriteria cri = new SearchCriteria(); cri.setKeyword("df"); cri.setSearchType("t"); //제목(title) logger.info("-------------------------------------"); logger.info(cri.toString()); List<BoardVO> list = dao.listSearch(cri); for (BoardVO boardVO : list) { logger.info(boardVO.getBno() + ": " + boardVO.getTitle()); //목록 출력 } logger.info("====================================="); logger.info("COUNT: " + dao.listSearchCount(cri)); //검색된 총 개수 }

 

11. BoardService.java --> 추가

<bash />
public List<BoardVO> listSearchCriteria(SearchCriteria cri) throws Exception; public int listSearchCount(SearchCriteria cri) throws Exception;

 

12. BoardServiceImpl.java  --> 추가

<bash />
@Override public List<BoardVO> listSearchCriteria(SearchCriteria cri) throws Exception { return dao.listSearch(cri); } @Override public int listSearchCount(SearchCriteria cri) throws Exception { return dao.listSearchCount(cri); }

 

13. SearchBoardController.java --> list 부분 수정 & 나머지 페이지들 추가

<bash />
package org.zerock.controller; import javax.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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 org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import org.zerock.domain.BoardVO; import org.zerock.domain.PageMaker; import org.zerock.domain.SearchCriteria; import org.zerock.service.BoardService; @Controller @RequestMapping("/sboard/*") // 부모 public class SearchBoardController { private static final Logger logger = LoggerFactory.getLogger(SearchBoardController.class); @Inject private BoardService service; //인스턴스 변수의 선언으로 BoardService 객체를 주입 받을 수 있게 설계 처리 //@ModelAttribute("cri")를 사용함으로써 cri객체를 list.jsp에 자동 전달 처리된다. @RequestMapping(value = "/list", method = RequestMethod.GET) public void list(@ModelAttribute("cri") SearchCriteria cri, Model model) throws Exception { logger.info(cri.toString()); //model.addAttribute("list", service.listCriteria(cri)); model.addAttribute("list", service.listSearchCriteria(cri)); PageMaker pageMaker = new PageMaker(); pageMaker.setCri(cri); //pageMaker.setTotalCount(service.listCountCriteria(cri)); pageMaker.setTotalCount(service.listSearchCount(cri)); model.addAttribute("pageMaker", pageMaker); //위 @ModelAttribute("cri") 생략 한다면 아래 구문을 추가해 준다. //model.addAttribute("cri", cri); } @RequestMapping(value = "/read", method = RequestMethod.GET) public void read(@RequestParam("bno") int bno, @ModelAttribute("cri") SearchCriteria cri, Model model) throws Exception { PageMaker pageMaker = new PageMaker(); pageMaker.setCri(cri); model.addAttribute("pageMaker", pageMaker); model.addAttribute(service.read(bno)); } @RequestMapping(value = "/modify", method = RequestMethod.GET) public void modifyGET(int bno, @ModelAttribute("cri") SearchCriteria cri, Model model) throws Exception { model.addAttribute(service.read(bno)); } @RequestMapping(value = "/modify", method = RequestMethod.POST) public String modifyPOST(BoardVO board, SearchCriteria cri, RedirectAttributes rttr) throws Exception { logger.info(cri.toString()); service.modify(board); rttr.addAttribute("page", cri.getPage()); rttr.addAttribute("perPageNum", cri.getPerPageNum()); rttr.addAttribute("searchType", cri.getSearchType()); rttr.addAttribute("keyword", cri.getKeyword()); rttr.addFlashAttribute("msg", "modify"); logger.info(rttr.toString()); return "redirect:/sboard/list"; } @RequestMapping(value = "/remove", method = RequestMethod.GET) public String remove(@RequestParam("bno") int bno, SearchCriteria cri, RedirectAttributes rttr) throws Exception { service.remove(bno); rttr.addAttribute("page", cri.getPage()); rttr.addAttribute("perPageNum", cri.getPerPageNum()); rttr.addAttribute("searchType", cri.getSearchType()); rttr.addAttribute("keyword", cri.getKeyword()); rttr.addFlashAttribute("msg", "delete"); return "redirect:/sboard/list"; } @RequestMapping(value = "/register", method = RequestMethod.GET) public void registGET() throws Exception { logger.info("regist get ..........."); } @RequestMapping(value = "/register", method = RequestMethod.POST) public String registPOST(BoardVO board, RedirectAttributes rttr) throws Exception { logger.info("regist post ..........."); logger.info(board.toString()); service.regist(board); rttr.addFlashAttribute("msg", "register"); return "redirect:/sboard/list"; } }

 

14. sboard/register.jsp

<bash />
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ include file="/WEB-INF/views/include/header.jsp" %> <center> <h3>WRITER PAGE</h3> <form method="post"> <table> <tr> <td>제목</td> <td><input name="title"></td> </tr> <tr> <td>내용</td> <td><textarea name="content" rows="3"></textarea></td> </tr> <tr> <td>작성자</td> <td><input name="writer"></td> </tr> <tr> <td></td> <td><button>Submit</button></td> </tr> </table> </form> </center> <%@ include file="/WEB-INF/views/include/footer.jsp" %>

 

15. sboard/read.jsp

<bash />
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ include file="/WEB-INF/views/include/header.jsp" %> <center> <h3>READ PAGE</h3> <table border=1 width=570> <tr> <td width=70>제목</td> <td width=500>${boardVO.title }</td> </tr> <tr> <td>내용</td> <td>${boardVO.content }</td> </tr> <tr> <td>작성자</td> <td>${boardVO.writer }</td> </tr> </table> <br> <table border=0 width=570> <tr> <td width=50%> <%-- <a href="list?&page=${param.page}">[리스트]</a> --%> <a href="list${pageMaker.makeSearch(pageMaker.cri.page)}">[list]</a> </td> <td width=50% align="right"> <%-- <a href="modify?bno=${boardVO.bno }&page=${param.page}">[수정]</a> --%> <!-- pageMaker.cri.page or 주소창에 이미 불러와있으므로 param.page도 가능 --> <a href="modify${pageMaker.makeSearch(pageMaker.cri.page)}&bno=${boardVO.bno }">수정</a> <a href="remove?bno=${boardVO.bno }">[삭제]</a> </td> </tr> </table> <!-- ajax 이용 --> <form role="pkt" name="pkt" method="get"> <input type="hidden" name="bno" value="${boardVO.bno }"> </form> <button class="btn-modify">수정</button> <button class="btn-delete">삭제</button> <button class="btn-list">리스트</button> </center> <%@ include file="/WEB-INF/views/include/footer.jsp" %>

 

16. sboard/modify.jsp

<bash />
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ include file="/WEB-INF/views/include/header.jsp" %> <center> <h3>MODIFY PAGE</h3> <form role="pkt" name="pkt" method="post"> <input type="hidden" name="bno" value="${boardVO.bno}"> <input type="hidden" name="page" value="${param.page}"> <table> <tr> <td>제목</td> <td><input name="title" value="${boardVO.title}"></td> </tr> <tr> <td>내용</td> <td><textarea name="content" rows="3">${boardVO.content}</textarea></td> </tr> <tr> <td>작성자</td> <td><input name="writer" value="${boardVO.writer}" readonly></td> </tr> <tr> <td></td> <td><button type="submit">Submit</button></td> </tr> </table> </form> </center> <%@ include file="/WEB-INF/views/include/footer.jsp" %>

 

'JAVA > spring' 카테고리의 다른 글

스프링 댓글 구현  (0) 2023.05.04
스프링 member 구현  (0) 2023.05.03
스프링 Board 구현_예외처리, 페이징  (1) 2023.05.02
스프링 Board 구현  (0) 2023.04.28
스프링 페이지 이동(변수 전달)  (0) 2023.04.28
profile

데일리로그C:

@망밍

포스팅이 도움됐다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!