<model>
1. BoardVO.java
package org.zerock.model;
import java.util.Date;
import lombok.Data;
@Data
public class BoardVO {
private Integer bno; // uid
private String title;
private String content;
private String writer; // 작성자
private Date regdate; //작성일
private int viewcnt; // 조회수
}
2. Criteria.java --> 페이지 & 검색관련
package org.zerock.model;
import lombok.Data;
@Data
public class Criteria {
private int page;
private int perPageNum;
private String field;
private String keyword;
//초기화
public Criteria() {
this.page = 1;
this.perPageNum =10;
}
//page - set, get 처리
public void setPage(int page) {
if(page <=0) {
this.page=1;
return;
}
this.page = page;
}
public int getPage() {
return page;
}
// perPageNum - set,get 처리
public void setPerPageNum(int perPageNum) {
if(perPageNum <=0) {
this.perPageNum = 10;
return;
}
this.perPageNum = perPageNum;
}
public int getPerPageNum() {
return perPageNum;
}
// limit 시작값
public int getPageStart() {
return (this.page -1)*this.perPageNum;
}
@Override // source - tostring
public String toString() {
return "Criteria [page=" + page + ", perPageNum=" + perPageNum + "]";
}
}
3. pageMaker.java --> 페이징처리
package org.zerock.model;
import java.io.ObjectInputStream.GetField;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import lombok.Data;
@Data
public class PageMaker {
private int totalCount;
private int startPage;
private int endPage;
private boolean prev;
private boolean next;
private int displayPageNum = 5;
private Criteria cri;
private void calcData() {
endPage =(int) Math.ceil(cri.getPage() / (double)displayPageNum) * displayPageNum;
startPage = (endPage - displayPageNum) +1;
// 마지막 블럭 처리
int tempEndPage = (int) Math.ceil((totalCount/(double)cri.getPerPageNum()));
if(endPage > tempEndPage) {
endPage = tempEndPage;
}
prev = startPage == 1? false:true;
next = endPage * cri.getPerPageNum() >= totalCount ? false:true;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
calcData();
}
// page 경로 처리
public String makeQuery(int page) {
UriComponents uriComponents = UriComponentsBuilder.newInstance()
.queryParam("page", page)
.queryParam("perPageNum", cri.getPerPageNum())
.build();
return uriComponents.toUriString();
}
// search & page 경로 처리
public String makeSearch(int page) {
UriComponents uriComponents = UriComponentsBuilder.newInstance()
.queryParam("page", page)
.queryParam("perPageNum", cri.getPerPageNum())
.queryParam("field", ((Criteria) cri).getField())
.queryParam("keyword", ((Criteria) cri).getKeyword())
.build();
return uriComponents.toUriString();
}
}
<dao>
4. BoardDAO.java
package org.zerock.dao;
import java.util.List;
import org.zerock.model.BoardVO;
import org.zerock.model.Criteria;
public interface BoardDAO {
public void insert(BoardVO b) throws Exception; // 글 작성
public List<BoardVO> list(Criteria cri) throws Exception; // 목록(페이징 page, perpageNum)
public BoardVO view(Integer bno) throws Exception; // 한건 데이터 불러오기
public void update(BoardVO b) throws Exception; // 수정
public void delete(Integer bno) throws Exception;// 삭제
public int tCount(Criteria cri) throws Exception; // 총게시물수
public int sCount(Criteria cri) throws Exception; // 검색된 게시물 수
}
5. BoardDAOImpl.java
package org.zerock.dao;
import java.util.List;
import javax.inject.Inject;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import org.zerock.model.BoardVO;
import org.zerock.model.Criteria;
@Repository
public class BoardDAOImpl implements BoardDAO{
@Inject
private SqlSession sqlSession;
private static String namespace = "org.zerock.mapper.boardMapper";
@Override
public void insert(BoardVO b) throws Exception {
sqlSession.insert(namespace+".insert", b);
}
@Override
public List<BoardVO> list(Criteria cri) throws Exception {
return sqlSession.selectList(namespace+".list", cri);
}
@Override // 상세페이지 + 조회수처리
public BoardVO view(Integer bno) throws Exception {
sqlSession.update(namespace+".viewCnt", bno);
return sqlSession.selectOne(namespace+".view",bno);
}
@Override
public void update(BoardVO b) throws Exception {
sqlSession.update(namespace+".update", b);
}
@Override
public void delete(Integer bno) throws Exception {
sqlSession.delete(namespace+".delete", bno);
}
@Override // 총 게시물수
public int tCount(Criteria cri) throws Exception {
return sqlSession.selectOne(namespace+".tCount", cri);
}
@Override // 검색 게시물 수
public int sCount(Criteria cri) throws Exception {
return sqlSession.selectOne(namespace+".sCount", cri);
}
}
<mapper>
6. boardMapper.xml
<?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="org.zerock.mapper.boardMapper">
<insert id="insert">
insert into board(title,content,writer) values(#{title},#{content},#{writer})
</insert>
<select id="list" resultType="org.zerock.model.BoardVO">
<![CDATA[
select * from board where bno > 0
]]>
<include refid="search"></include>
<![CDATA[
order by bno desc limit #{pageStart},#{perPageNum}
]]>
</select>
<!-- 검색 추가한 총게시물수 -->
<select id="sCount" resultType="int">
<![CDATA[
select count(bno) from board where bno > 0
]]>
<include refid="search"></include>
</select>
<!-- 총게시물수 -->
<select id="tCount" resultType="int">
<![CDATA[
select count(bno) from board where bno > 0
]]>
</select>
<!-- 조회수 -->
<update id="viewCnt">
update board set viewcnt = viewcnt + 1 where bno = #{bno}
</update>
<select id="view" resultType="org.zerock.model.BoardVO">
select * from board where bno = #{bno}
</select>
<update id="update">
update board set title=#{title}, content=#{content} where bno=#{bno}
</update>
<delete id="delete">
delete from board where bno=#{bno}
</delete>
<!-- 검색 (sql문 뒤에 (1) "str" 처리하는 것과 동일) -->
<sql id="search">
<if test = "field != null">
<!-- CONCAT 함수 필수(like 비교를 위해서) -->
<if test="field == 't'.toString()"> <!-- title이라면 -->
and title like CONCAT('%', #{keyword}, '%')
</if>
<if test="field == 'c'.toString()"> <!-- content라면 -->
and content like CONCAT('%', #{keyword}, '%')
</if>
<if test="field == 'w'.toString()"> <!-- writer이라면 -->
and writer like CONCAT('%', #{keyword}, '%')
</if>
<if test="field == 'tc'.toString()"> <!-- title, content라면 -->
and ( title like CONCAT('%', #{keyword}, '%') OR content like CONCAT('%', #{keyword}, '%'))
</if>
<if test="field == 'cw'.toString()"> <!-- content, writer이라면 -->
and ( content like CONCAT('%', #{keyword}, '%') OR writer like CONCAT('%', #{keyword}, '%'))
</if>
<if test="field == 'tcw'.toString()"> <!-- title, content, writer이라면 -->
and
( title like CONCAT('%', #{keyword}, '%')
OR content like CONCAT('%', #{keyword}, '%')
OR writer like CONCAT('%', #{keyword}, '%'))
</if>
</if>
</sql>
</mapper>
7. BoardDAOTest.java
package org.zerock.controller;
import java.util.List;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import org.zerock.dao.BoardDAO;
import org.zerock.model.BoardVO;
import org.zerock.model.Criteria;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/**/root-context.xml" })
public class BoardDAOTest {
@Inject
private BoardDAO dao;
private static Logger logger = LoggerFactory.getLogger(BoardDAOTest.class);
//@Test //글 작성
public void testinsert() throws Exception {
BoardVO b = new BoardVO();
b.setTitle("제목2");
b.setContent("내용2");
b.setWriter("1111");
//dao.insert(b);
//logger.info("작성완료==");
}
//@Test // list
public void testlist() throws Exception {
//List<BoardVO> list = dao.list();
//for(BoardVO b: list) {
//logger.info(b.toString());
//}
}
//@Test // view
public void testview() throws Exception {
//logger.info(dao.view(2).toString());
}
//@Test // 수정
public void testupdate() throws Exception {
BoardVO b = new BoardVO();
b.setBno(2);
b.setTitle("제목2 수정");
b.setContent("내용2 수정");
//dao.update(b);
//logger.info("수정완료==");
}
//@Test // 삭제
public void testdelete() throws Exception {
//dao.delete(2);
//logger.info("삭제완료 ==");
}
//@Test
public void testpage() throws Exception {
//logger.info("page====");
int page = 1;
//List<BoardVO> list = dao.listPage(page);
//for(BoardVO b : list) {
//logger.info(b.getBno() + ":" + b.getTitle() );
//}
}
//@Test
public void testCri() throws Exception {
Criteria cri = new Criteria();
//cri.setPage(2);
//cri.setPerPageNum(5);
//logger.info(cri.toString());
//List<BoardVO> list = dao.listCri(cri);
//for(BoardVO b : list) { // 향상된 for문
//logger.info("cri test====" + b.getBno() + ":" + b.getTitle());
//}
}
//@Test
public void testURI2() throws Exception {
UriComponents uriComponents = UriComponentsBuilder.newInstance()
.path("/{module}/{page}")
.queryParam("bno", 12)
.queryParam("perPageNum", 10)
.build()
.expand("board", "read") // path 변수에 들어갈 녀석들
.encode();
//logger.info("/board/read?bno=12&perPageNum=10");
// logger.info(uriComponents.toString());
}
//@Test
public void testSearch() throws Exception {
Criteria cri = new Criteria();
//cri.setKeyword("ㅍㅍ");
//cri.setField("t");
//logger.info("-------------------------------------");
//logger.info(cri.toString());
List<BoardVO> list= dao.list(cri);
//for(BoardVO b : list) {
//logger.info(b.getBno() + ": " + b.getTitle());
//}
//logger.info("-------------------------------------");
//logger.info("count : " + dao.sCount(cri));
}
}
<service>
8. BoardService.java
package org.zerock.service;
import java.util.List;
import org.zerock.model.BoardVO;
import org.zerock.model.Criteria;
public interface BoardService {
public void insert(BoardVO b) throws Exception; // 글 작성
public List<BoardVO> list(Criteria cri) throws Exception; // 목록(페이징 page, perpagenum)
public BoardVO view(Integer bno) throws Exception; // 한건 데이터 불러오기
public void update(BoardVO b) throws Exception; // 수정
public void delete(Integer bno) throws Exception;// 삭제
public int listTC(Criteria cri) throws Exception; // 총게시물수
public int listSC(Criteria cri) throws Exception;
}
9. BoardServiceImpl.java
package org.zerock.service;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import org.zerock.dao.BoardDAO;
import org.zerock.model.BoardVO;
import org.zerock.model.Criteria;
@Service
public class BoardServiceImpl implements BoardService{
@Inject
private BoardDAO dao;
@Override
public void insert(BoardVO b) throws Exception {
dao.insert(b);
}
@Override
public List<BoardVO> list(Criteria cri) throws Exception {
return dao.list(cri);
}
@Override
public BoardVO view(Integer bno) throws Exception {
return dao.view(bno);
}
@Override
public void update(BoardVO b) throws Exception {
dao.update(b);
}
@Override
public void delete(Integer bno) throws Exception {
dao.delete(bno);
}
@Override
public int listTC(Criteria cri) throws Exception {
return dao.tCount(cri);
}
@Override
public int listSC(Criteria cri) throws Exception {
return dao.sCount(cri);
}
}
<controller>
10. BoardController.java
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.model.BoardVO;
import org.zerock.model.Criteria;
import org.zerock.model.PageMaker;
import org.zerock.service.BoardService;
@Controller
@RequestMapping("/board/*")
public class BoardController {
private static final Logger logger = LoggerFactory.getLogger(BoardController.class);
@Inject
private BoardService service;
//글 작성
@RequestMapping(value="/write", method=RequestMethod.GET)
public void writeGET(BoardVO b) throws Exception {
logger.info("write get==");
}
@RequestMapping(value="/write", method=RequestMethod.POST)
public String writePOST(BoardVO b, Model model) throws Exception {
logger.info("write post==");
logger.info(b.toString());
service.insert(b);
model.addAttribute("msg", "write");
return "redirect:/board/list";
}
// 목록
@RequestMapping(value="/list", method=RequestMethod.GET)
public void list(@ModelAttribute("cri") Criteria cri, Model model) throws Exception {
logger.info("list === page====");
logger.info(cri.toString());
model.addAttribute("list", service.list(cri));
//model.addAttribute("count", service.listSC(cri));
PageMaker pm = new PageMaker();
pm.setCri(cri);
//pm.setTotalCount(100);
//pm.setTotalCount(service.listTC(cri));
pm.setTotalCount(service.listSC(cri));
model.addAttribute("pageMaker", pm);
}
// view
@RequestMapping(value ="/view", method=RequestMethod.GET)
public void read(@RequestParam("bno") int bno, @ModelAttribute("cri") Criteria cri, Model model) throws Exception {
logger.info("view get====");
PageMaker pm = new PageMaker();
pm.setCri(cri);
model.addAttribute("pageMaker", pm);
model.addAttribute(service.view(bno));
}
// 수정 get
@RequestMapping(value = "/modify", method = RequestMethod.GET)
public void modifyGET(int bno, @ModelAttribute("cri") Criteria cri, Model model) throws Exception {
model.addAttribute(service.view(bno));
}
//수정 post
@RequestMapping(value = "/modify", method = RequestMethod.POST)
public String modifyPOST(BoardVO b, Criteria cri, RedirectAttributes rttr) throws Exception {
logger.info(cri.toString());
service.update(b);
rttr.addAttribute("page", cri.getPage());
rttr.addAttribute("perPageNum", cri.getPerPageNum());
rttr.addAttribute("field", cri.getField());
rttr.addAttribute("keyword", cri.getKeyword());
rttr.addFlashAttribute("msg", "modify");
logger.info(rttr.toString());
return "redirect:/board/list";
}
// 삭제
@RequestMapping(value = "/remove", method = RequestMethod.GET)
public String remove(@RequestParam("bno") int bno, Criteria cri, RedirectAttributes rttr) throws Exception {
service.delete(bno);
rttr.addAttribute("page", cri.getPage());
rttr.addAttribute("perPageNum", cri.getPerPageNum());
rttr.addAttribute("field", cri.getField());
rttr.addAttribute("keyword", cri.getKeyword());
rttr.addFlashAttribute("msg", "delete");
return "redirect:/board/list";
}
}
<jsp>
1. list.jsp
<%@ 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+"&field=${cri.field}&keyword=${cri.keyword}";
}
</script>
<center>
<table border=0 width=800>
<tr>
<th>Total : ${pageMaker.totalCount}</th>
<td>
<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="field">
<option value="n" ${cri.field == null?'selected':''}>---</option>
<option value="t" ${cri.field eq 't'?'selected':''}>제목</option>
<option value="c" ${cri.field eq 'c'?'selected':''}>내용</option>
<option value="w" ${cri.field eq 'w'?'selected':''}>작성자</option>
<option value="tc" ${cri.field eq 'tc'?'selected':''}>제목/내용</option>
<option value="cw" ${cri.field eq 'cw'?'selected':''}>내용/작성자</option>
<option value="tcw" ${cri.field eq 'tcw'?'selected':''}>제목/내용/작성자</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=800 style="border-collapse: collapse;">
<tr>
<th style="width:10px">No</th>
<th>제목</th>
<th>작성자</th>
<th style="width:200px">작성일</th>
<th style="width: 60px">조회수</th>
</tr>
<c:set var="numbering" value="${pageMaker.totalCount - (pageMaker.cri.page - 1) * pageMaker.cri.perPageNum }" />
<c:forEach var="boardVO" items="${list}">
<tr>
<td>${numbering}</td>
<td><a href="view${pageMaker.makeSearch(pageMaker.cri.page)}&bno=${boardVO.bno}">${boardVO.title}</a></td>
<td>${boardVO.writer}</td>
<td><fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss" value="${boardVO.regdate}"/> </td>
<td>${boardVO.viewcnt}</td>
</tr>
<c:set var="numbering" value="${numbering -1 }" />
</c:forEach>
</table>
<br>
<table border=0 width=700>
<tr>
<td align=right><a href="write">글쓰기</a></td> <!-- ${pageMaker.makeSearch(pageMaker.cri.page)} -->
</tr>
</table>
<table border=1 width=200 align=center>
<tr>
<c:if test="${pageMaker.prev}">
<td><a href="list${pageMaker.makeSearch(pageMaker.startPage - 1)}">[이전]</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>
<td><a href="list${pageMaker.makeSearch(idx)}">${idx}</a></td>
<c:if test="${pageMaker.cri.page == idx}"></b></c:if>
</td>
</c:forEach>
<c:if test="${pageMaker.next && pageMaker.endPage > 0}">
<td><a href="list${pageMaker.makeSearch(pageMaker.endPage +1)}">[다음]</a></td>
</c:if>
</tr>
</table>
</center>
<%@ include file="/WEB-INF/views/include/footer.jsp" %>
2. write.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/views/include/header.jsp" %>
<center>
<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" %>
3. view.jsp
<%@ 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=800>
<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=800>
<tr>
<td width=50%>
<a href="list${pageMaker.makeQuery(pageMaker.cri.page)}">[리스트]</a>
</td>
<td width=50% align="right">
<a href="/board/modify${pageMaker.makeQuery(pageMaker.cri.page)}&bno=${boardVO.bno }">수정</a>
<a href="/board/remove?bno=${boardVO.bno }">[삭제]</a>
</td>
</tr>
</table>
</center>
<%@ include file="/WEB-INF/views/include/footer.jsp" %>
4. modify.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/views/include/header.jsp" %>
<center>
<form name="f1" 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' 카테고리의 다른 글
id,pw 찾기(이중탭, ajax) (0) | 2023.05.16 |
---|---|
총정리 (0) | 2023.05.10 |
member_fullcode (0) | 2023.05.09 |
이클립스에 spring 연동시키는 법 (0) | 2023.05.08 |
스프링 첨부파일 구현 (0) | 2023.05.08 |