반응형
1)게시판생성
1-1)board테이블 생성
1-2) Controller , Mapper (SQL가짐), Dao(DB와의연결,sql실행)생성
1-3) Board클래스
2)WriteForm(작성하는곳)
2-1)layout적용
2-2)BoardController(write매핑부분)
2-3) BoardDao(write관련 메서드)
2-4) BoardMapper (sql을 가지는 인터페이스 Mapper)
3)list
3-1) list.jsp (view)
3-2) list매핑부분(Controller)
3-3) BoardDao ( boardCount , list 메서드)
3-4) BoardMapper
4)info
4-1) Controller(info매핑부분)
4-2) BoardDao의 numSearch , readCntAdd메서드
4-3) BoardMapper인터페이스
1) 게시판생성
1-1) board 테이블 생성
create table board(
num int auto_increment primary key ,-- 게시글 번호(기본키)
writer varchar(30), -- 작성자
pass varchar(20), -- 비밀번호
title varchar(100), --게시글 제목
content varchar(2000), --게시글 내용
file1 varchar(200), --첨부파일명
boardid varchar(2), --게시판 종류 (1.공지사항 , 2.자유게시판)
regdate datetime, -- 게시글등록일자
readcnt int(10), --조회수(상세보기 시 증가)
grp int, --답글 작성시 원글의 게시글 번호
grplevel int(3), -- 답글의레벨(0:원글 1:원글의답글 2:답글의답글...)
grpstep int(5) --그룹의 출력 순서
);
1-2) Controller , Mapper , Dao 생성
1-3) Board클래스(Bean)
package model.board;
import java.util.Date;
public class Board {
private int num;
private String writer;
private String pass;
private String title;
private String content;
private String file1;
private String boardid;
private Date regdate;
private int readcnt;
private int grp;
private int grplevel;
private int grpstep;
//getter , setter , toString 생성
}
2) writeForm
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- /webapp/view/board/writeForm.jsp -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시글등록</title>
</head>
<body>
<form action="write" method="post" enctype="multipart/form-data"
name="f">
<h2 class="text-center">게시판 글쓰기</h2>
<table class="table">
<tr>
<td>글쓴이</td>
<td><input type="text" name="writer" class="form-control"></td>
</tr>
<tr>
<td>비밀번호</td>
<td><input type="password" name="pass" class="form-control"></td>
</tr>
<tr>
<td>제목</td>
<td><input type="text" name="title" class="form-control"></td>
</tr>
<tr>
<td>내용</td>
<td><textarea rows="15" name="content" id="content"
class="form-control"></textarea></td>
</tr>
<tr>
<td>첨부파일</td>
<td><input type="file" name="file1"></td>
</tr>
<tr>
<td colspan="2"><a href="javascript:inputcheck()" class="btn btn-outline-secondary">[게시물등록]</a></td>
</tr>
</table>
</form>
<script type="text/javascript">
function inputcheck() {
f = document.f;
if (f.writer.value == "") {
alert("글쓴이 입력");
f.writer.focus();
return;
}
if (f.pass.value == "") {
alert("비밀번호입력");
f.pass.focus();
return;
}
if (f.title.value == "") {
alert("제목입력");
f.title.focus();
return;
}
f.submit(); //submit발생
}
</script>
</body>
</html>
2-1) layout적용
/java/sitemesh/SiteMeshFilter.java
에 다음과같은 문장을 맨 아래에 넣어준다.
builder.addDecoratorPath("/board/*", "/layout/layout.jsp");
2-2) BoardController(write매핑부분)
package controller;
import java.io.File;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.oreilly.servlet.MultipartRequest;
import gdu.mskim.MskimRequestMapping;
import gdu.mskim.RequestMapping;
import model.board.Board;
import model.board.BoardDao;
@WebServlet(urlPatterns = {"/board/*"},
initParams = {@WebInitParam(name="view",value="/view/")}
)
public class BoardController extends MskimRequestMapping {
private BoardDao dao = new BoardDao();
@RequestMapping("write")
public String write(HttpServletRequest request ,
HttpServletResponse response) {
String path = request.getServletContext().getRealPath("/")+"/upload/board/";
//C:/java/workspace/.metadata/
// .plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/model2Study/upload/board/
File f = new File(path);
if(!f.exists()) {
f.mkdirs();
}
int size = 10*10*1024;//10M(업로드파일의 최대크기)
MultipartRequest multi = null;
try {
multi = new MultipartRequest(request, path,size,"UTF-8");
}
catch (Exception e) {
e.printStackTrace();
}
Board board = new Board();
board.setWriter(multi.getParameter("writer"));
board.setPass(multi.getParameter("pass"));
board.setTitle(multi.getParameter("title"));
board.setContent(multi.getParameter("content"));
board.setFile1(multi.getFilesystemName("file1")); //업로드된 파일명
String boardid = (String)request.getSession().getAttribute("boardid");
if(boardid==null) {
boardid="1"; // 공지사항 기본게시판으로설정
}
board.setBoardid(boardid);//게시판종류 1:공지사항 , 2:자유게시판
if(board.getFile1()==null) {
board.setFile1("");
}
int num = dao.maxnum();
board.setNum(++num); // 게시글 키값(게시글번호)
board.setGrp(num); // 그룹번호
String msg="게시물등록실패";
String url = "writeForm";
if(dao.insert(board)) {
return "redirect:list?boardid="+boardid;
}
request.setAttribute("msg", msg);
request.setAttribute("url", url);
return "alert";
}
}
2-3) BoardDao( DB와의 연결을 위한 파일)
package model.board;
import java.util.HashMap;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import model.MyBatisConnection;
import model.mapper.BoardMapper;
public class BoardDao {
private Class<BoardMapper> cls = BoardMapper.class;
private Map<String, Object> map = new HashMap<>();
public int maxnum() {
SqlSession session = MyBatisConnection.getConnection();
try {
return session.getMapper(cls).maxnum();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
MyBatisConnection.close(session);
}
return 0;
}
public boolean insert(Board board) {
SqlSession session = MyBatisConnection.getConnection();
try {
if(session.getMapper(cls).insert(board)) {
return true;
}
return false;
}
catch (Exception e) {
e.printStackTrace();
}
finally {
MyBatisConnection.close(session);
}
return false;
}
}
2-4) BoardMapper (sql을 설정하는 인터페이스 Mapper)
package model.mapper;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import model.board.Board;
public interface BoardMapper {
//num이 null이라면 0을 반환해줌
@Select("select ifnull(max(num),0) from board")
int maxnum();
@Insert("insert into board(writer,pass,title,content,file1,regdate,"
+ "readcnt, grp , grplevel , grpstep , boardid) "
+ " values(#{writer},#{pass},#{title},#{content},#{file1},now(),"
+ "0, #{grp} , #{grplevel} , #{grpstep} , #{boardid})")
boolean insert(Board board);
}
3) list
3-1) list.jsp (view)
writeForm이 정상적으로 작성됐다면
그 데이터의 boardid를 파라미터로 갖는
list 실행
/view/board/list.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" %>
<!DOCTYPE html>
<html>
<!--
첨부파일이 존재하는 게시물의 제목앞에 @ 표시
-->
<head>
<meta charset="UTF-8">
<title>게시물목록</title>
</head>
<body>
<h2>${boardName}</h2>
<table class="table">
<c:if test="${boardcount == 0}">
<tr><td colspan="5">등록된게시글이없어요</td></tr>
</c:if>
<c:if test="${boardcount > 0}">
<tr><td colspan="5" style="text-align:right">글 갯수:${boardcount}</td></tr>
<tr>
<th width="8%">번호</th><th width="50%">제목</th>
<th width="14%">작성자</th><th width="17%">등록일</th>
<th width="11%">조회수</th>
</tr>
<c:set var="num" value="${num}" /> <!-- (controller에서만듬)num속성을 c:set으로 지정 -->
<c:forEach var="b" items="${list}" >
<tr><td>${num}</td>
<c:set var="num" value="${num-1}" /> <!-- num을 -1해줌 -->
<td style="text-align: left">
<c:if test="${!empty b.file1}"><a href="../upload/board/${b.file1}">@</a></c:if>
<c:if test="${empty b.file1}"> </c:if>
<a href="info?num=${b.num}">${b.title}</a></td>
<td>${b.writer}</td>
<td>${b.regdate}</td>
<td>${b.readcnt}</td>
</c:forEach>
<tr><td colspan="5" align="center">
<c:if test="${pageNum <= 1}">[이전]</c:if>
<c:if test="${pageNum > 1}">
<a href="list?pageNum=${pageNum-1}">[이전]</a>
</c:if>
<c:forEach var="a" begin="${startpage}" end="${endpage}">
<c:if test="${a == pageNum}"><a href="#">[${a}]</a></c:if><!-- 현재페이지를 누르면 아무일도일어나지않음 -->
<c:if test="${a != pageNum}"><!-- 다른페이지클릭시 해당 pageNum으로넘어감 -->
<a href="list?pageNum=${a}">[${a}]</a>
</c:if>
</c:forEach>
<c:if test="${pageNum >= maxpage}">[다음]</c:if>
<c:if test="${pageNum < maxpage}">
<a href="list?pageNum=${pageNum+1}">[다음]</a>
</c:if>
</td></tr>
</c:if>
<tr><td colspan="5" style="text-align:right">
<p align="right"><a href="writeForm">[글쓰기]</a></p>
</td></tr>
</table>
</body>
</html>
3-2) list매핑부분(Controller)
/*
* 1.한 페이지당 10건의 게시물을 출력하기.
* pageNum이라는 파라미터값 => 없는경우는 1로설정
* boardid파라미터값 => 있는경우 session에등록
* 2.최근등록된 게시물이 가장 위쪽
* 3.db에서 해당페이지에 출력될 내용만 조회해 화면에출력
*/
@RequestMapping("list")
public String list(HttpServletRequest request ,
HttpServletResponse response) {
//pageNum파라미터가존재하면 파라미터값을 pageNum변수에 저장
//pageNum 파라미터가없으면 파라미터값을 pageNum변수는 1로저장
int pageNum = 1;
try {
pageNum = Integer.parseInt(request.getParameter("pageNum"));
} catch (NumberFormatException e) {}
//boardid파라미터값
String boardid = request.getParameter("boardid");
if(boardid==null || boardid.trim().equals("")) {
boardid = "1";//boardid파라미터가 없는경우 '1'로설정
}
//board값을 session에 등록
request.getSession().setAttribute("boardid", boardid);
int limit = 10;//페이지당 출력되는 게시물의건수
int boardcount = dao.boardCount(boardid);//현재등록된 게시물건수
//pageNum에 해당하는 게시물목록을 최대10개 조회
List<Board> list = dao.list(boardid,pageNum,limit);
int maxpage = (int)((double)boardcount/limit + 0.95);
/*
* maxpage : 필요한페이지 갯수
* 게시물건수 maxpage
* 10 10.0/10 +0.95 = (int)1.95 => 1
* 11 11.0/10 + 0.95 = (int)2.05 => 2
* 500 500.0/10 + 0.95 = (int)50.95 => 50
*/
int startpage = ((int)(pageNum/10.0 + 0.9) - 1) * 10 +1;
/*
* startpage : 화면에출력되는 시작페이지
* 현재페이지(pageNum) startpage endPage
* 1 1 10
* 12 11 20
* 43 41 50
*/
int endpage = startpage+ 9;//한화면에는 10개의 페이지번호만보임
if(endpage>maxpage) { //maxpage보다 크다면 endpage는 maxpage로 바뀐다
endpage = maxpage;
}
//ex) 11개의 게시물밖에없는데 10개의페이지가 필요할까? 2개의페이지(maxpage)만있으면된다!
String boardName = "공지사항";
if(boardid.equals("2")) {
boardName = "자유게시판";
}
int num = boardcount - (pageNum-1)*limit;
/*
* num : 목록번호(boardid별로 다름)
* boardid=1 이 13개의 게시글을 가지고있고 1페이지인경우
* 13- 0*10 = 13
* 2페이지인경우
* 13 - 10 = 3
*/
request.setAttribute("boardName", boardName); //게시판이름
request.setAttribute("boardcount", boardcount);//게시판종류별 등록된게시물
request.setAttribute("boardid", boardid); //게시판코드
request.setAttribute("num", num);
request.setAttribute("pageNum", pageNum);//현재페이지
request.setAttribute("list", list);//현재페이지에출력한 게시물목록
request.setAttribute("startpage", startpage);//페이지시작번호
request.setAttribute("endpage", endpage);//페이지마지막번호
request.setAttribute("maxpage", maxpage);//페이지의 갯수
return "board/list";
}
3-3) BoardDao ( boardCount , list 메서드)
DB를 연결하는 역할 , 인터페이스에서 쿼리를실행시킬거임
public int boardCount(String boardid) {
SqlSession session = MyBatisConnection.getConnection();
try {
return session.getMapper(cls).boardCount(boardid);
}
catch (Exception e) {
e.printStackTrace();
}
finally {
MyBatisConnection.close(session);
}
return 0;
}
public List<Board> list(String boardid, int pageNum, int limit) {
SqlSession session = MyBatisConnection.getConnection();
map.clear();
map.put("boardid", boardid);
map.put("start", (pageNum-1) * limit);
map.put("limit", limit);
try {
return session.getMapper(cls).list(map);
}
catch (Exception e) {
e.printStackTrace();
}
finally {
MyBatisConnection.close(session);
}
return null;
}
3-4 ) BoardMapper
Mapper역할 (sql구문 실행)
@Select("select count(*) from board where boardid=#{val}")
int boardCount(String boardid);
@Select("select * from board where boardid=#{boardid}"
+ " order by grp desc , grpstep asc limit #{start},#{limit}")
// grp 를 내림차순으로 정렬해 가장 최신의 글이 맨 위로올라갈거임
//start번에서부터 limit개 조회해
List<Board> list(Map<String, Object> map);
4) info ( list에서 제목을누르면 이동하는곳)
num을 파라미터로 가짐
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시물상세보기</title>
</head>
<body>
<h2 class="">${boardName}</h2>
<table class="table">
<tr><th width="20%">글쓴이</th> <!-- Controller에서 b속성(boarder객체)를 넘겼음 -->
<td width="80%" style="text-align:left">${b.writer}</td></tr>
<%-- ${b.xxx} : b(board)에 getxx프로퍼티 --%>
<tr><th>제목</th><td style="text-align:left">${b.title}</td></tr>
<tr><th>내용</th><td><table style="width:100%; height:250px;">
<tr><td style="border-width:0px; vertical-align:top; text-align:left; margin:0px; padding:0px;">
${b.content}</td></tr></table></td></tr>
<tr><th>첨부파일</th>
<td><c:if test="${empty b.file1}"> </c:if>
<c:if test="${!empty b.file1}">
<a href="../upload/board/${b.file1}">${b.file1}</a>
</c:if></td></tr>
<tr><td colspan="2" class="w3-center">
<a href="replyForm?num=${b.num}">[답변]</a>
<a href="updateForm?num=${b.num}">[수정]</a>
<a href="deleteForm?num=${b.num}">[삭제]</a>
<a href="list?boardid=${b.boardid}">[목록]</a>
</td></tr>
</table>
</body>
</html>
4-1) Controller(info매핑부분)
@RequestMapping("info")
public String info(HttpServletRequest request, HttpServletResponse response) {
int num = Integer.parseInt(request.getParameter("num"));
String readcnt = request.getParameter("readcnt");
// String boardid = (String)request.getSession().getAttribute("boardid");
// b : num 값의 게시물 데이터 저장
Board b = dao.numSearch(num);
// readcnt 파라미터의 값이 "f"인 경우 조회수 증가 안함.
if(readcnt == null || !readcnt.trim().equals("f")) {
dao.readcntAdd(num); // 조회수 증가
}
String boardid = b.getBoardid();
String boardName = "공지사항";
if(boardid.equals("2")) {
boardName = "자유게시판";
}
request.setAttribute("b",b);
request.setAttribute("boardName", boardName);
request.setAttribute("boardid", boardid);
return "board/info";
}
4-2 ) BoardDao의 numSearch , readcntAdd메서드
public Board numSearch(int num) {
SqlSession session = MyBatisConnection.getConnection();
try {
return session.getMapper(cls).numSearch(num);
} catch (Exception e) {
e.printStackTrace();
}
finally {
MyBatisConnection.close(session);
}
return null;
}
public int readcntAdd(int num) {
SqlSession session = MyBatisConnection.getConnection();
try {
return session.getMapper(cls).readcntAdd(num);
} catch (Exception e) {
e.printStackTrace();
}
finally {
MyBatisConnection.close(session);
}
return 0;
}
4-3 ) BoardMapper인터페이스
numSeach , readcntAdd메서드
(실행하고자하는 sql를 가지고있음)
@Select("select * from board where num=#{num}")
Board numSearch(int num);
@Update("update board set readcnt=readcnt+1 where num=#{v}")
int readcntAdd(int num);
'JSP' 카테고리의 다른 글
54일차의 내용추가(book 관련) (1) | 2025.04.19 |
---|---|
부트캠프54일 (답변게시판 , 수정 , 삭제 , 권한) (0) | 2025.04.18 |
부트캠프52일차(framwork설명,동적쿼리,인터페이스이용한Mapper , model2Study 리팩토링) (0) | 2025.04.16 |
부트캠프51일차 (model2 idchk) , (MyBatis시작 , 세팅법 사용법) (0) | 2025.04.15 |
부트캠프50일차(Model2 : mail , id pw search , password수정 , pictureForm) (0) | 2025.04.14 |