220406~14 세미
0406
글 작성 -> 파일명 안 넘어가는 오류 해결
목록 -> 공지, 게시글 따로 분리해 출력 완료
글 내용 -> 내용 출력+첨부파일+다운로드 완료
글 수정 -> 첨부파일 변경시 기존파일 삭제까지 완료
글 삭제 -> 첨부파일 삭제까지 완료
내일 할 일: 답글 달기, 답글달린 글 삭제했을 때 리스트에 출력 어떻게 할지 + (가능하다면)권한 별로 컬럼, 버튼 숨기기
경로가 왜 계속 바뀌는지... 진짜 돌아버릴것같애
--> 해결한듯함.
내 문제는 자꾸 경로 사이에 저장된 디렉토리가 끼었다 안 끼었다 하는 문제였는데
경로대로 쫓아가보니 git 저장하는 과정에서 예전 프로젝트 이름으로 된 빈 디렉토리가 남아있었고 그 안에 프로젝트를 풀어버려서 사이에 이상한 경로가 하나 더 낀 것이었음
싹 삭제하고 다시 clone으로 받아와 실행하니 원래대로 경로가 출력됨을 확인함
0407
다른 조원들 거 pull로 땡겨와서 내 코드 수정하는 데에 한세월 보내고
답글기능 완료
목록에 체크박스 숨김처리 완료
본문에 계정 별로 버튼 다르게 출력시키는거 완료
-----0408 목표
관리자: 리스트에서 글 다중 삭제 (체크박스) 기능
글 검색기능
++ 더 시간이 된다면 댓글 기능을 한번 알아보자
0408
다중 선택 -> 삭제 sql
파일 다중 삭제 dao 따로 돌리기
select로 string[] mb_num 값 돌려서
체크박스 코드
목록에 삭제 표시 <form action="<%=request.getContextPath() %>/member_board_multidel.do" method="post" name="form1" id="form1"> <c:if test="${sessionScope.member_grade==1 }"> <td colspan=4 align="right" style="border-top:0;"><input type="submit" class="btn btn-outline-secondary btn-sm" value="삭제"></td> </c:if> <!-- 삭제는 관리자가 들어갈 때만 보이게 설정... checked 위에. --> </tr> </table> |
전체 체크박스 <c:if test="${sessionScope.member_grade==1 }"> <th width="50" ><input type="checkbox" id="allchk" name="allchk" ></th> <!-- 전체 체크 --> </c:if> <!-- 관리자가 들어갈 때만 컬럼이 보이게 설정 --> |
각 글마다 체크박스 <c:if test="${sessionScope.member_grade==1 }"> <td align=center> <input type="checkbox" name="chk" value="${b.mb_Num }"> </td> </c:if> |
script.js $(document).ready(function(){ //체크박스 유효성 $("form[name='form1']").submit(function(){ if($("input:checkbox[name=chk]:checked").length < 1){ alert("삭제할 글을 체크해주세요"); return false; } if($("input:checkbox[name=chk]:checked").length >=1){ var del=confirm("삭제하시겠습니까?"); // 확인/취소 메시지 뜨게 if(del) document.form.submit(); //확인 누르면 서브밋 else return false; } }); //#allchk 클릭 시 전체 체크박스 체크/해제 기능 $("#allchk").click(function(){ if($("#allchk").is(":checked")) $("input[name=chk]").prop("checked", true); else $("input[name=chk]").prop("checked", false); }); }); }); |
multidel.java String[] mb_num=request.getParameterValues("chk"); //체크된 글번호 저장 String path = request.getRealPath("mb_upload"); //본문에 파일 있을 경우 파일들 저장되는 경로 int result=dao.multidel(mb_num, path); //dao로~ |
dao //파일 먼저 삭제 String sql="select mb_file from member_board where mb_num=?"; for(int i=0; i<mb_num.length; i++) { pstmt=con.prepareStatement(sql); pstmt.setString(1, mb_num[i]); rs=pstmt.executeQuery(); if(rs.next()) { //첨부파일이 있다면 File file=new File(path); File[] f= file.listFiles(); for(int j=0; j<f.length; j++) { if(f[j].getName().equals(rs.getString("mb_file"))) { f[j].delete(); //파일 삭제 } } } } pstmt.close(); //글 삭제 sql="delete from member_board where mb_num=?"; pstmt=con.prepareStatement(sql); for(int i=0; i<mb_num.length; i++) { pstmt.setString(1, mb_num[i]); pstmt.addBatch(); //글번호 입력한 sql문을 쌓아두기 } int[] cnt=pstmt.executeBatch(); //실행결과 배열로 저장 for(int i=0; i<cnt.length; i++) { if(cnt[i]==-2) { //성공시 result++; //하나씩 증가시킴 } if(mb_num.length==result) con.commit(); //모두 성공하면 커밋 else con.rollback(); //문제 있으면 롤백 |
결과![]() |
검색기능
//카운트를 하나로 묶어서 처리할 수 있으면 해야 함
//내생각엔... sel이랑 find값이 따로 주어지지 않으면 null로 들어가게 하고
//dao에서 if else문으로 분리해서 sql문을 두 개 만드는 게 좋을 것 같음
sql = "select * from ( select rownum rnum, no, ";
sql += "writer, passwd, subject, content from ";
if(sell!=null){ //검색값이 있으면 있는 버전으로 쿼리 추가
sql += "(select * from testboard where "+sel+" like '%"+find+"%' order by no desc)) ";
} else { //없으면 없는 버전으로 쿼리 추가
sql += "(select * from testboard order by no desc)) ";
}
sql += "where rnum >= ? and rnum <= ?";
그리고 그냥 count>0이면 출력하게 넣는거야
어차피 list 뽑아온 시점에서 전체 또는 검색 둘 중 하나만 뽑혔으니까.
list.java
sel, find값을 받고 값이 존재하지 않는다면 전체 리스트 뽑기
값이 존재하면 검색해서 리스트 뽑기
listcount도 이미 만들어둔게 있으니, 값이 존재하는 경우로 위에랑 묶기
값 존재할 경우랑 존재하지 않는 경우를 if문으로 나눠서 각각 처리하는게 나을듯
그리고 각각 처리해서 나온 카운트값을 listcount로 넘기게 하고.
둘 중 하나만 처리될테니 그걸 board로 넣어서 request.setA를 하면 될 것 같고.
select * from ( select rownum rnum, board.* from
(select * from member_board where mb_subject like '%1%' or mb_content like '%1%' order by mb_ref desc, mb_seq asc) board)
where rnum >= 1;
검색의 경우 선생님이 수업을 해주신 걸 참고함
예제 파일을 확인해보니, 검색 옵션과 검색어가 존재하지 않을 때 (전체 목록 출력할 때) 받은 값이 null로 뜬다는 데에서 힌트를 얻음
서비스 클래스에서 조건마다 다른 dao를 호출하는 것보다 일단 dao를 실행하고 그 안에서 조건에 따라 다른 sql문을 저장해 실행시키는 게 좀 더 괜찮아보임
dao 만든거 하나 코드 여기 표 안에 넣어놓고
조건은 검색어가 없을 경우 ->전체 출력
검색어가 있는데 옵션이 제목/내용/글쓴이 -> 두번째 출력
검색어 있고 옵션이 제목+내용 -> 세번째 출력
이렇게 할 경우 sql문만 조건에 따라 바꿔주면 되고 실행은 조건문 밖에서 시키면 되니, 나름 효율적이지 않나..? 싶음...?
검색 시 체크박스 유효성 검사가 자꾸 실행되고 submit으로 값 넘길 시 multidel로 넘어가는 현상
내가 js 파일을 만져보다 else로 return false를 추가했었는데 이게 원인이 아닌가 싶음
한 페이지에 폼 여러개를 둘 때 해결 방법 -> form[name='form_name'] 으로 유효성 검사를 한정시키면 된다
주의할 점: 하나의 폼 안에 submit 버튼이 두 개 존재하면 안 됨. 각각 다른 폼으로 만들어야 함!
-----------까지 0408에 했음
검색폼 <form name="form2" id="form2" action="<%=request.getContextPath() %>/member_board_list.do" method="post" > <div class="container text-center d-flex align-items-center" style="font-family: 'Nanum Gothic', sans-serif; width:30%"> <select name="sel" class="form-control form-control-sm text-center" id="sel1" style="width:40%"> <option value="all">제목+내용</option> <option value="id">작성자</option> <option value="mb_subject">제목</option> <option value="mb_content">내용</option> </select> <input type=text name="find" id="find" class="form-control form-control-sm" aria-label="Search" > <button type="submit" class="btn btn-primary btn-sm flex-shrink-0" id="searchBtn" style="width:20%">검색</button> </div> </form> |
script.js //검색 $("form[name='form2']").submit(function(){ if($("#find").val()==""){ alert("검색어를 입력하세요"); $("#find").focus(); return false; } }); |
list.java List<member_board_dto> mb_list=new ArrayList<member_board_dto>(); //목록 mb_list=dao.getMBList(startRow, endRow, sel, find); //리스트 출력 |
DAO if(sel==null && find==null) { //전체 목록 (검색X) sql="select * from (select rownum rnum, board.* from "; sql+=" (select *from member_board order by mb_ref desc, mb_seq asc) board) "; sql+=" where rnum>=? and rnum<=?"; } else if(!sel.equals("all")){ //제목+내용 제외 sql = "select * from ( select rownum rnum, board.* from "; sql += "(select * from member_board where "+sel+" like '%"+find+"%' order by mb_ref desc, mb_seq asc) board) "; sql += "where rnum >= ? and rnum <= ?"; } else { //제목+내용 sql = "select * from ( select rownum rnum, board.* from "; sql += "(select * from member_board where mb_subject like '%"+find+"%' or mb_content like '%"+find+"%' order by mb_ref desc, mb_seq asc) board) "; sql += "where rnum >= ? and rnum <= ?"; } |
결과![]() |
----0411 할 것
메인 레이아웃 만들고 액션태그로 각 jsp파일 가져와서 누덕누덕 붙여보기.. 실행만 되면 된다
book 테이블에서 등록일순 정렬해서 rnum=1,2,3 하나씩 가져와서 메인에 보이게 해보기?
검색 부분은 도서검색부분 해결하시면 그 경로로 붙이면 될듯
카로셀은... 머 여기까진 생각하지 말자
아무튼 프론트 레이아웃은 대충 내 생각 비슷한걸 찾았으니 이런 느낌으로 만들어보겠다? 얘기하면 댈듯?
프론트는 세세하게 게시판 규격 맞춰 수정
배포 시 이미지 엑박 뜨는 문제
0411
관리자: 미반납 리스트 -> 반납일 기준으로 asc
회원 : 대출 내역 -> 반납 처리 -> rent테이블에서 삭제된 후 location.href=으로 대출 내역 다시 들어가기
책 상세 페이지에서, 로그인한 상태로 대여 -> book_Num, id 가져옴
rent_Num -> primary key 받고 sysdate, sysdate+14일것이고
미반납 리스트 -> 포린키로 book테이블 num 값 받았으니까 이 두 테이블을 조인해서 전체 출력
---> 받는 값은 어차피 book_dto rent_dto를 둘다 써야한단말이야 그럼 리턴을 list로 받을때 데이터형을 한정시키지 말자고
rent_dto rent=new rent_dto();
book_dto book=net boo_dto();
만들어놓고 둘 다 받아서 리스트에 집어넣고 뺄 때 foreach문에서... 변수가 다 다르니까? 변수만 다르게 해서 빼보면 될듯?
---해결---> 선생님한테 여쭤보니까 그냥.. 임의로 그 컬럼값을 rent_dto에 추가시키면 된다고 하셔서, book 테이블 값 일부의 변수를 추가시킨 후 list에 저장하는 방식을 사용함
rentlist -> rent_dao adminRentList
select * from (select rownum rnum, list.* from (select rent.rent_num, rent.id, rent.book_num, book.book_name, book.writer, book.publisher, rent.rent_date, rent.return_date from rent, book where rent.book_num=book.book_num order by rent.return_date asc) list ) where rnum>=? and rnum<=?;
rentcount -> rent_dao getCount
select count(*) from rent;
위 sql문으로 리스트랑 글 갯수 구했고 출력 무난하게 시켰음 + 한 페이지 당 20개씩 뜨게 페이징 처리 완.
반납 처리는 회원 대출 내역 다른 조원님이 한걸 받아서 반납 신청에 서블릿 연결함
delete 처리 후 return값을 request 영역으로 넘겨서, alert으로 반납처리 되었습니다 뜨는 jsp 파일로 forward 이동시키고 (returnalert.jap) 그 jsp에서 location.href로 list로 이동~
<c:if test="${result == 1 }">
<script>
alert("반납되었습니다");
location.href="./rentListAction.do";
</script>
</c:if>
rejected non fast forward 오류 -> 그냥 다 삭제시키고 다시 클론함... 이게 나한텐 제일 편해..
+++ 관리자 -> 회원 상세페이지 -> 대출내역 추가
기존 id값으로 상세내역 받아서 list에 저장 후 request 영역으로 넘겨서 foreach로 뿌리면 됨
0412
color: rgba(33, 37, 41, 0.8);
<td colspan=10 align="left" style="border-top:0;"> <c:if test="${not empty find}">[${find }] 검색 결과</c:if> 총 ${listcount} </td>
<c:if test="${not empty sessionScope.id }">
<td colspan=7 align="right" style="border-top:0;"><input type="button" class="btn btn-outline-secondary btn-sm" value=" 작성 " onClick="location.href='./member_board_writeform.do'"></td>
</c:if>
background-color: #3b4147;
background-color: rgba(59, 65, 71, 0.7);
#212529
#F8E1C2
text-shadow: -1px 0 #000, 0 1px #000, 1px 0 #000, 0 -1px #000;
#6f42c1
#ffc800;
0414
프론트는 세세하게 게시판 규격 맞춰 수정
관리자 메뉴바 만들어 적용
배포 시 이미지 엑박 뜨는 문제 -> outputstream 사용 (써놓고도 이해가 잘... 선생님한테 나중에 물어볼 것)
0415~18
게시판 규격 통일시키고 세세한 오류 수정 예정