0901 web 기능구현

onnbi·2022년 10월 14일
0

web

목록 보기
3/8
post-thumbnail

servlet jsp 기능 구현

데이터 베이스의 CRUD를 기본으로 하여 사용자의 요청을 받아 Cotroller를 통해 Service와 소통하고 Dao로 DB로부터 데이터를 받아 다시 Controller - View로 응답한다

구현 순서

ex) 회원가입

  1. 쿼리문을 작성한다

    ex) insert into member_tbl values(?, ?, ?, ?);

  2. 쿼리문에서 사용자에게 입력받아야 하는 값이 존재하는지 파악한다

  3. 입력받을 값이 필요하면, 입력받는 페이지로 이동 (Frm.jsp)

  4. 입력받을 값이 필요하면, 입력받을 페이지에서 데이터를 입력받아 서버로 전송(servlet.do)

  5. Servlet을 통해 DB작업 진행

  6. 성공/실패 따른 페이지를 제작하여 사용자에게 보여준다

ex) 전체 조회

  1. 쿼리문을 작성한다

    ex) select * from member_tbl;

  2. 입력받을 값이 없으므로 페이지 이동 X

  3. 서블릿에게 요청하여 DB 작업진행

  4. 성공 실패에 따른 페이지 제작하여 사용자에게 제공

게시판 만들기

  1. 데이터베이스 테이블 제작 (충분히 insert 하여 여러 페이지를 검증한다)
  2. 자바 패키지 만들기
  3. 글목록 만들기

ROWMUM 사용 쿼리

SELECT * FROM (SELECT ROWNUM AS RNUM, N.* FROM (SELECT * FROM NOTICE ORDER BY NOTICE_NO DESC)N) WHERE RNUM BETWEEN 1 AND 10;
    /*인라인뷰*/
  1. 정렬
  2. rownum 붙이고
  3. rownum 기준으로 조건을 주어 출력

jsp에서 js사용

  • opener (나를 열어준 페이지를 찾을 때)
  • location.href (js에서 연결해줄 때 사용)
<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();
profile
aelatte coding journal

0개의 댓글