본문 바로가기

프로그래밍/JAVA & SPRING

[LifeSoft] spring 23강 게시판 만들기4( 게시물 수정, 파일 첨부, 첨부파일 삭제, 게시물 삭제)

반응형

-- 첨부파일 테이블
drop table attach cascade constraints;
create table attach (
  fullName varchar2(150) not null, -- 첨부파일 이름(uuid)
  bno number not null,  -- 게시물 번호
  regdate date default sysdate,  -- 업로드 날짜
  primary key(fullName)
);

-- bno 컬럼에 foreign key 설정

alter table attach add constraint fk_board_attach

foreign key(bno) references board(bno);

foreign key bno는 board테이블의 게시물 번호(board(bno))이어야 한다.

 

insert into attach values ('a.txt', 1000, sysdate); -- 정상 입력

insert into attach values ('b.txt', 2000, sysdate); -- 오류 뜬다.

명령의 14 행에서 시작하는 중 오류 발생 -
insert into attach values ('b.txt', 2000, sysdate)
오류 보고 - ORA-02291: 무결성 제약조건(SPRING.FK_BOARD_ATTACH)이 위배되었습니다- 부모 키가 없습니다

테이블과 테이블 관계를 설정할때 foreign key를 설정하는게

데이터를 정확하게 처리할 수 있게 한다.

 

 

-- board 테이블의 bno 컬럼을 위한 시퀀스 생성

drop sequence seq_board;

create sequence seq_board

start with 1

increment by 1;

 

 

 

게시물 수정이 잘 되면

첨부파일 업로드하는 로직과

업로드된 데이터를 불러오는 로직을 구성한다.

board/view.jsp 페이지가 로드될때 ajax로 첨부파일 목록을 가져온다.

 

$(function(){
    listAttach();
 });
function listAttach() {
  $.ajax({
    type: "post",
    url: "${path}/board/getAttach/${dto.bno}",
    success: function(list){
      $(list).each(function(){
      var fileInfo = getFileInfo(this);
      var html = "<div><a href='"+fileInfo.getLink+"'>"+fileInfo.fileName+"</a>  ";
      html += "<a href='#' class='file_del' data-src='"+this+"'>[삭제]</a></div>";
      $("#uploadedList").append(html);
      console.log("listAttach===="+html);
    });
  } 
});
}

 

 

첨부파일 리스트가 구현되면 [삭제]기능을 구현한다.

[삭제]를 클릭하면 AjaxUploadController를 매핑url '/upload/deleteFile'로 호출한다.

삭제버튼을 누르면 업로드 폴더(D:\upload\오늘날자)에 있는 파일이 삭제된다.

그러나 DB의 파일은 아직 지워지지 않는다.

AjaxUploadController의 deleteFile()메소드에 디비 레코드를 삭제하는 로직을 추가한다.

 

게시물 보기에서 수정사항을 입력하다가(업로드 포함)

취소를 누르면 업로드 폴더의 파일을 삭제해야 한다.

아니면 업로드 기능을 잠시 멈추게 해야 한다.

수정 버튼을 누르기 전에는 DB(attach table)에는 반영이 안된다.

이 기능은 글쓰기 로직에 추가해 본다.

 

mapper.xml을 구성한다.

 

 <insert id="insert">
  insert into board (bno, title, content, writer,show)
  values
  (seq_board.nextval, #{title}, #{content}, #{writer}, #{show})
 </insert>
 <insert id="addAttach">
  insert into attach (fullName,bno)
  values ( #{fullName}, seq_board.currval )
 </insert>

 

 

 

글쓰기 기능은 트랜잭션 처리(board table. attach table기록)를 해야 한다.

먼저 board 테이블에 레코드를 기록하고

boardDao.create(dto)

그 현재 bno(seq_board.currval)를 가져와서 file upload관련 레코드를 attach에 기록한다.

bno는 foreign key로 board와 attach 테이블을 연결하고 있다.

** 현재 글번호를 가져올 수 있는 것은 트랜잭션 처리중이기 때문에 가능한 듯 하다.**

 

글쓰기 전에 board, reply, attach table의 내용을 지워서

번호가 꼬이는 것을 방지하자.

**  foreign key가 있어서 삭제시 오류가 생긴다.

삭제 순서를 이렇게 한다. attach -> reply -> board

 

board/write.jsp

현재까지 글쓰기 로직에서는 파일 첨부기능이 빠져있었다.

jsp에 파일 첨부 스크립트를 추가한다.

아래 코드는 첨부파일(이미지, 일반)을 업로드 폴더에 저장하고

화면에 리스트를 보여주는 기능을 한다.

 

 

// 드래그 기본효과 막음 (도롭하면 이미지가 새창으로 열림)
 $(".fileDrop").on("dragenter dragover", function(e){  
  e.preventDefault();
 });
 $(".fileDrop").on("drop", function(e){
  e.preventDefault();
....
}

 

 

 

BoardService create()메소드에 파일 정보를 저장하는 코드을 넣는다.

  String[] files = dto.getFiles();
  if(files==null) return;
  for(String name : files) {
   boardDao.addAttach(name);
  }

그리고 반듯이 Transaction 처리를 해준다.

아직 글번호가 확정이 안된 상태이다.

board 테이블에 글이 저장된 후에 글번호를 가져와서

boardDao.addAttach(name);할때 넣어줘야 한다.(mapper에서 넣어준다)

 

@Transactional
@Override
public void create(BoardDTO dto) throws Exception {
  boardDao.create(dto);
  // 추가: 첨부파일 정보 저장
  String[] files = dto.getFiles();
  if(files==null) return;
  for(String name : files) {
    boardDao.addAttach(name);
  }
}

 

 

BoardDAO의 addAttach()메소드를 완성한다.

 

public void addAttach(String fullName) {
  sqlSession.insert("board.addAttach", fullName);
}

 

 

boardMapper.xml에서 파일첨부 코드를 추가한다.

 

 <insert id="addAttach">
  insert into attach (fullName, bno) values
  ( #{fullName}, seq_board.currval )
 </insert>

 

 

글쓰기시를 하면 board 테이블은 기록되고 attach 테이블은 등록이 안된다.

트랜잭션 처리를 했는데 안된다는 것은

첨부파일 관련 정보가 없어서 실행이 안되기 때문에 글등록이 되는 것이다.

 

글등록할때 파일정보를 hidden으로 넘겨주는 코드를 추가한다.

write.jsp의 스크립트를 아래와 같이 수정한다.

 

 

$("#btnSave").on("click", function(){
  var str="";
  $("#uploadedList .file").each(function(i){
   str+= "<input type='hidden' name='files["+i+"]' value='"+$(this).val()+"'>";   
  });
   
  $("#form1").append(str);  
  document.form1.submit(); 
});[code]
 
 
글삭제 view.jsp
[code]$("#btnDelete").click(function(){
  if(confirm("삭제하시겠습니까?")) {
   document.form1.action="${path}/board/delete.do";
   document.form1.submit();
  } 
});

 

 

BoardController의 delete()메소드에서 추가로 할 작업은

게시물 삭제시 댓글과 첨부파일을 함께 삭제하거나

댓글이나 첨부파일이 하나라도 있으면 삭제를 막는 로직을 넣을 수 있다.

 

 

@RequestMapping("delete.do")
public String delete(int bno) throws Exception {
  // 댓글과 첨부파일 관련 로직
  boardService.delete(bno);
  return "redirect:/board/list.do";
}