데이터 베이스의 CRUD를 기본으로 하여 사용자의 요청을 받아 Cotroller를 통해 Service와 소통하고 Dao로 DB로부터 데이터를 받아 다시 Controller - View로 응답한다
ex) 회원가입
쿼리문을 작성한다
ex) insert into member_tbl values(?, ?, ?, ?);
쿼리문에서 사용자에게 입력받아야 하는 값이 존재하는지 파악한다
입력받을 값이 필요하면, 입력받는 페이지로 이동 (Frm.jsp)
입력받을 값이 필요하면, 입력받을 페이지에서 데이터를 입력받아 서버로 전송(servlet.do)
Servlet을 통해 DB작업 진행
성공/실패 따른 페이지를 제작하여 사용자에게 보여준다
ex) 전체 조회
쿼리문을 작성한다
ex) select * from member_tbl;
입력받을 값이 없으므로 페이지 이동 X
서블릿에게 요청하여 DB 작업진행
성공 실패에 따른 페이지 제작하여 사용자에게 제공
SELECT * FROM (SELECT ROWNUM AS RNUM, N.* FROM (SELECT * FROM NOTICE ORDER BY NOTICE_NO DESC)N) WHERE RNUM BETWEEN 1 AND 10;
/*인라인뷰*/
<script>
$(".changeLevel").on("click", function(){
// 클릭한 버튼을 기준으로 해당 회원의 번호
const memberNo = $(this).parent().parent().children().eq(1).text();
// 클릭한 버튼 기준으로 선택한 등급
const memberLevel = $(this).parent().prev().children().val();
// 필요한 데이터는 모두 수집 > 컨트롤러 호출
location.href = "/changeLevel.do?memberNo="+memberNo+"&memberLevel="+memberLevel;
})
</script>
public NoticePageData selectNoticeList(int reqPage) {
Connection conn = JDBCTemplate.getConnection();
// 한 페이지 당 게시물 수 지정 > 10개로 지정
int numPerPage = 10;
// 요청페이지 1page > 가장 최신 글 1~10번 필요
// reqPage == 1 > 최신글 1~10번
// 요청페이지 2page > 가장 최신 글 11~20번 필요
// reqPage == 2 > 최신글 11~20번
// reqPage == 3 > 최신글 21~30번
int end = numPerPage*reqPage;
int start = end-numPerPage+1;
ArrayList<Notice> list = dao.selectNoticeList(conn, start, end);
for(Notice n : list) {
System.out.println(n.getNoticeTitle());
}
// 전체 페이지를 알아야 목록 페이지 수를 계산할 수 있음 > 데이터 베이스 필요 > 서비스에서 작업
// *페이징 처리*
// 전체 페이지 수 계산 > 전체 게시물 수 조회
int totalCount = dao.selectNoticeCount(conn); // DB에서 count(*)로 select
int totalPage = 0;
if(totalCount%numPerPage == 0) { // 전체글 수를 한 페이지 총 글수로 나눴을 때 나누어 떨어지면
totalPage = totalCount/numPerPage;
}else {
totalPage = totalCount/numPerPage+1; // 나누어 떨어지지 않으면 나머지 처리할 페이지 1+
}
// *페이지 네비게이션*
// 지정해 줘야 하는 값 : 페이지 네비게이션 사이즈
int pageNaviSize = 5;
// 페이지 네비게이션 시작번호 지정
int pageNo = ((reqPage-1)/pageNaviSize)*pageNaviSize+1;
// reqPage 1~5 > 1 2 3 4 5 > ((reqPage-1)/pageNaviSize) 몫은 무조건 0
// reqPage 6~10 > 6 7 8 9 10 > ((reqPage-1)/pageNaviSize) 몫은 무조건 1
// reqPage 11~15 > 11 12 13 14 15 > ((reqPage-1)/pageNaviSize) 몫은 무조건 2
// 페이지 네비게이션 제작 시작
String pageNavi = "<ul class='pagination circle-style'>";
// < 이전버튼
if(pageNo != 1) { // 1이면 이전으로 가는 아이콘 필요 X
pageNavi += "<li>";
pageNavi += "<a class='page-item' href='/noticeList.do?reqPage="+(pageNo-1)+"'>";
pageNavi += "<span class='material-icons'>chevron-left</span>";
pageNavi += "</a></li>";
}
// 페이지 숫자
for(int i=0; i<pageNaviSize;i++) { // pageNaviSize = 5
if(pageNo == reqPage) { //선택한 페이지일 때 = 해당 페이지에 active class
pageNavi += "<li>";
pageNavi += "<a class='page-item active-page' href='/noticeList.do?reqPage="+pageNo+"'>";
pageNavi += pageNo;
pageNavi += "</a></li>";
}else { // 선택한 페이지가 아닐 때
pageNavi += "<li>";
pageNavi += "<a class='page-item' href='/noticeList.do?reqPage="+pageNo+"'>";
pageNavi += pageNo;
pageNavi += "</a></li>";
}
pageNo++;
if(pageNo>totalPage) { // ++한 페이지 넘버가 총 페이지 수를 넘으면 반복문 종료
break;
}
}
// 다음버튼 >
if(pageNo<=totalPage) {
pageNavi += "<li>";
pageNavi += "<a class='page-item' href='/noticeList.do?reqPage="+pageNo+"'>";
pageNavi += "<span class='material-icons'>chevron-right</span>";
pageNavi += "</a></li>";
}
pageNavi = "</ul>";
// 값 2개를 넘겨줘야 할 때 > 객체를 생성하여 넘긴다
NoticePageData npd = new NoticePageData(list, pageNavi);
JDBCTemplate.close(conn);
return npd;
}
첨부파일 있을 시, method="post" enctype="multipart/form-data"
속성 반드시 추가 / 첨부파일과 글작성하여 서블릿으로 전달
input type 삭제는 value를 넣을 수 없다
수정하지 않은 값은 유지하여 가져가는 것이 필요
기존 값으로 업데이트해주는 로직을 만들어야 한다
<%if(n.getFilepath() != null) {%>
<img src="/img/file.png" width="16px" class="delFile">
<span class="delFile"><%=n.getFilename() %></span>
<button type="button" class="btn bc1 delFile">삭제</button>
<input type="file" name="upfile" style="display:none;">
<input type="hidden" name="oldFilename" value="<%=n.getFilename() %>>">
<input type="hidden" name="oldFilepath" value="<%=n.getFilepath() %>>">
<%}else { %>
<input type="file" name="upfile">
<%} %>
넘기는 값 : 제목, 첨부파일, 기존첨부파일이름, 기존첨부파일경로, 내용, 글번호
--------------------서블릿
새 첨부파일이 들어온다 < 기존 파일을 지우고 들어오는지, 기존파일이 없었는지
새 첨부파일이 들어오지 않는다 < 기존 파일을 지우고 들어오는지, 기존파일이 없는지
<input type="hidden" name="noticeNo" value="<%=n.getNoticeNo() %>">
<!-- 조건절에 들어갈 글번호 hidden -->
<input type="hidden" name="status" value="stay">
<!-- 첨부파일이 있었는데 지웠으면 stay를 변경해서 제출할 status -->
<script>
$("button.delFile").on("click", function(){
$(".delFile").hide();
$(this).next().show();
$("[name=status]").val("delete"); // 삭제버튼 누르면 stay > delete
})
</script>
-> 새 첨부파일이 없는 경우
-> 기존 파일을 삭제 case4
-> 기존 파일을 유지 (title이나 content만 수정한 경우) case3
-> 새 첨부파일이 있는 경우 -> 기존 파일을 삭제 case5
-> 새 첨부파일이 없는 경우 case1
-> 새 첨부파일이 있는 경우 case2
case4, case5 -> 기존 파일을 유지 -> status로 판단
case1, case2 - > filename, filepath를 db업데이트
어차피 바뀐 값으로 db 덮어씌우기 작업을 할 것이기 때문에 case3의 경우는 filename, filepath를 이전 old로 넣어준다
pstmt = conn.prepareStatement(query);
pstmt.setString(1, nc.getNcWriter());
pstmt.setString(2, nc.getNcContent());
pstmt.setInt(3, nc.getNoticeRef());
/*
if(nc.getNcRef()==0) {
pstmt.setString(4, null); // 오라클은 number타입 변수에도 null이 가능하기 때문
}else {
pstmt.setInt(4, nc.getNcRef());
}
*/
pstmt.setString(4, (nc.getNcRef()==0)?null:String.valueOf(nc.getNcRef()));
//String으로 넣어도 오라클이 알아서 number형으로 처리
result = pstmt.executeUpdate();