일반게시판
< 게시글 수정 >
1) 게시글 수정 폼 요청
2) 게시글 수정 요청
- BOARD테이블 UPDATE
- 첨부파일 바뀐거면 ATTACHMENT테이블 UPDATE
- 첨부파일 생긴거면 ATTACHMENT테이블 INSERT
1) 게시글 수정 폼 요청
1. 게시글 수정 폼 요청
- 게시글 상세보기 페이지에 버튼 작성
- 로그인한 사용자이고, 해당 게시글의 작성자일 경우에만 '수정하기' 버튼 활성화
<% if (loginUser != null && loginUser.getUserId().equals(b.getBoardWriter())) { %>
<a href="<%= contextPath %>/updateForm.bo?bno=<%= b.getBoardNo() %>" class="btn btn-sm btn-warning">수정하기</a>
<a href="<%= contextPath %>/delete.bo?bno=<%= b.getBoardNo() %>" class="btn btn-sm btn-danger">삭제하기</a>
<% } %>
2. BoardUpdateFormController.java
- 매핑값 : /updateForm.bo
- Service단에 세 번 요청 (CATEGORY테이블 조회 / BOARD테이블 조회 / ATTACHMENT테이블 조회)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 카테고리 전체 조회해오기
ArrayList<Category> list = new BoardService().selectCategoryList();
// 해당 글 번호 뽑기(bno)
int boardNo = Integer.parseInt(request.getParameter("bno"));
// 글 번호에 해당하는 BOARD테이블의 행 조회
Board b = new BoardService().selectBoard(boardNo);
// 글 번호에 해당하는 ATTACHMENT테이블의 행 조회
Attachment at = new BoardService().selectAttachment(boardNo);
// 값 담기
request.setAttribute("list", list);
request.setAttribute("b", b);
request.setAttribute("at", at);
// 응답 화면 => 포워딩
request.getRequestDispatcher("views/board/boardUpdateForm.jsp").forward(request, response);
}
3. BoardService.java (자바클래스)
- selectCategoryList() : 게시글 작성 시, 사용했던 메소드 그대로 사용
public ArrayList<Category> selectCategoryList() {
Connection conn = getConnection();
ArrayList<Category> list = new BoardDao().selectCategoryList(conn);
close(conn);
return list;
}
- selectBoard() : 글번호로 조회한 게시글의 정보를 반환
public Board selectBoard(int boardNo) {
Connection conn = getConnection();
Board b = new BoardDao().selectBoard(conn, boardNo);
close(conn);
return b;
}
- selectAttachment() : 게시글 번호로 조회한 게시글첨부파일의 정보를 반환
public Attachment selectAttachment(int boardNo) {
Connection conn = getConnection();
Attachment at = new BoardDao().selectAttachment(conn, boardNo);
close(conn);
return at;
}
4. BoardDao.java (자바클래스)
- selectCategoryList()
public ArrayList<Category> selectCategoryList(Connection conn) {
// SELECT문 => ResultSet => 7번 여러행 => List
ArrayList<Category> list = new ArrayList();
PreparedStatement pstmt = null;
ResultSet rset = null;
String sql = prop.getProperty("selectCategoryList");
try {
pstmt = conn.prepareStatement(sql);
rset = pstmt.executeQuery();
while(rset.next()) {
list.add(new Category(rset.getInt("CATEGORY_NO"), rset.getString("CATEGORY_NAME")));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rset);
close(pstmt);
}
return list;
}
- SQL문 (SELECT)
<entry key="selectCategoryList">
SELECT CATEGORY_NO, CATEGORY_NAME
FROM CATEGORY
</entry>
- selectBoard()
public Board selectBoard(Connection conn, int boardNo) {
// SELECT -> ResultSEt => PK (한 건만, 무조건) => Board
Board b = null;
PreparedStatement pstmt = null; // 초기값이 당연히! null이므로 안쓰는게 맞음
ResultSet rset = null;
String sql = prop.getProperty("selectBoard");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, boardNo);
rset = pstmt.executeQuery();
if(rset.next()) {
b = new Board();
b.setBoardNo(rset.getInt("BOARD_NO"));
b.setBoardTitle(rset.getString("BOARD_TITLE"));
b.setBoardContent(rset.getString("BOARD_CONTENT"));
b.setCategory(rset.getString("CATEGORY_NAME"));
b.setCreateDate(rset.getDate("CREATE_DATE"));
b.setBoardWriter(rset.getString("USER_ID"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rset);
close(pstmt);
}
return b;
}
- SQL문
<entry key="selectBoard">
SELECT
BOARD_NO,
CATEGORY_NAME,
BOARD_TITLE,
BOARD_CONTENT,
USER_ID,
CREATE_DATE
FROM
BOARD B
LEFT
JOIN
CATEGORY USING(CATEGORY_NO)
JOIN
MEMBER ON (BOARD_WRITER = USER_NO)
WHERE
BOARD_NO = ?
AND
B.STATUS = 'Y'
</entry>
- selectAttachment()
public Attachment selectAttachment(Connection conn, int boardNo) {
// SELECT -> ResultSet -> 첨부파일 한 개 (일반게시판) => Attachment
Attachment at = null;
PreparedStatement pstmt = null; // 초기값이 당연히! null이므로 안쓰는게 맞음
ResultSet rset = null;
String sql = prop.getProperty("selectAttachment");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, boardNo);
rset = pstmt.executeQuery();
if(rset.next()) {
at = new Attachment();
at.setFileNo(rset.getInt("FILE_NO"));
at.setOriginName(rset.getString("ORIGIN_NAME"));
at.setChangeName(rset.getString("CHANGE_NAME"));
at.setFilePath(rset.getString("FILE_PATH"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rset);
close(pstmt);
}
return at;
}
- SQL문
<entry key="selectAttachment">
SELECT
FILE_NO,
ORIGIN_NAME,
CHANGE_NAME,
FILE_PATH
FROM
ATTACHMENT
WHERE
REF_BNO = ?
</entry>
5. boardUpdateForm.jsp (JSP)
- 이미 작성된 내용을 가지고 수정 화면을 구성
<form action="<%= contextPath %>/update.bo" method="post" enctype="multipart/form-data" id="update-form">
<!-- 제목, 내용, 카테고리, 제출버튼, 첨부파일 -->
<!-- 숨겨서 넘어갈 값들을 같이 적어줌 -->
<input type="hidden" value="<%= b.getBoardNo() %>" name="bno">
<table align="center">
<tr>
<th width="150">카테고리</th>
<td width="600">
<select name="category">
<% for(Category c : list) { %>
<option value="<%= c.getCategoryNo() %>"><%= c.getCategoryName() %></option>
<% } %>
</select>
<script>
$(function() { // 해당 카테고리가 선택될 수 있도록 조건
$('#update-form option').each(function() {
if($(this).text() == '<%= b.getCategory() %>') {
$(this).attr('selected', 'true');
}
});
});
</script>
</td>
</tr>
<tr>
<th>제목</th>
<td><input type="text" name="title" required value="<%= b.getBoardTitle() %>"></td>
</tr>
<tr>
<th>내용</th>
<td>
<textarea name="content" style="resize: none;" rows="10" required><%= b.getBoardContent() %></textarea>
</td>
</tr>
<tr>
<th>첨부파일</th>
<!-- 기존 파일이 존재했다면 원본파일명 보여주기 -->
<% if(at != null) { %>
<td>
<%= at.getOriginName() %> // 원본파일명
<input type="hidden" value="<%= at.getFileNo() %>" name="originFileNo">
<input type="hidden" value="<%= at.getChangeName() %>" name="originFileName">
<!-- 기존의 첨부파일이 있을 때만 파일번호, 파일명을 숨겨서 같이 넘겨줌 -->
</td>
<% } %>
<td><input type="file" name="reUpfile"></td>
</tr>
</table>
<br>
<div align="center">
<button type="reset">취소하기</button>
<button type="submit">작성하기</button>
</div>
</form>
2) 게시글 수정 요청
1. BoardUpdateCotroller.java (Servlet)
- form태그의 submit타입의 버튼으로 요청
- enctype이 mutipart/form-data이므로 MultipartRequest객체 생성
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1) POST => 인코딩
request.setCharacterEncoding("UTF-8");
// 2) 값 뽑기
// multipart/form-data로 잘 전송되었을 때만 내용이 수행되게끔 조건
if(ServletFileUpload.isMultipartContent(request)) {
// 1. 전송 파일 용량 제한 int maxSize => 10Mbyte
int maxSize = 1024 * 1024 * 10;
// 2. 전달된 파일을 저장시킬 폴더의 물리적 경로를 알아내기 String savePath
String savePath = request.getSession().getServletContext().getRealPath("/resources/board_upfiles"); // Session객체 생성 -> Application객체 생성 -> 경로 파악
// Multipart객체를 생성함으로 서버에 파일이 업로드
MultipartRequest multiRequest = new MultipartRequest(request, savePath, maxSize, "UTF-8", new MyFileRenamePolicy());
// UPDATE BOARD : 공통적으로 수행해야하는 SQL문
// 2) 값 뽑기 request => multiRequest
int boardNo = Integer.parseInt(multiRequest.getParameter("bno"));
String category = multiRequest.getParameter("category");
String title = multiRequest.getParameter("title");
String content = multiRequest.getParameter("content");
// 3) VO가공 - BOARD관련
Board b = new Board();
b.setBoardNo(boardNo);
b.setCategory(category);
b.setBoardTitle(title);
b.setBoardContent(content);
// 실제 첨부파일이 있을 경우에만 Attachment 객체 생성
Attachment at = null;
// 새로운 첨부파일명을 반환해주는 메소드를이용해서 첨부파일이 있는지 확인
if(multiRequest.getOriginalFileName("reUpfile") != null) {
// 원본이름 반환 / 첨부파일이 없으면 null 반환
at = new Attachment();
at.setOriginName(multiRequest.getOriginalFileName("reUpfile"));
at.setChangeName(multiRequest.getFilesystemName("reUpfile"));
at.setFilePath("resources/board_upfiles");
if(multiRequest.getParameter("originFileNo") != null) { // 기존파일이 있을 경우
// 기존 파일이 가지고 있던 파일 번호를 at에 담을 것
at.setFileNo(Integer.parseInt(multiRequest.getParameter("originFileNo")));
// 기존에 서버에 존재하던 첨부파일 삭제
new File(savePath + multiRequest.getParameter("originFileName")).delete();
} else {
// 새로운 첨부파일은 있었지만 기존 파일은 없을 경우 -> INSERT
// 어떤 게시글의 첨부파일인지 boardNo(REF_BNO)
at.setRefBno(boardNo);
}
}
// 4) 서비스 요청
int result = new BoardService().updateBoard(b, at);
// 5) 결과에 따른 응답 뷰 지정
if (result > 0) {
request.getSession().setAttribute("alertMsg", "게시글이 성공적으로 수정되었습니다.");
response.sendRedirect(request.getContextPath() + "/detail.bo?bno=" + boardNo);
} else {
request.setAttribute("errorMsg", "게시글 수정 실패!");
request.getRequestDispatcher("views/common/errorPage.jsp").forward(request, response);
}
}
}
2. BoardService.java (자바클래스)
- updateBoard()
- Dao단에 두 번 요청
- ㄱ.BOARD테이블 UPDATE 요청
- ㄴ.첨부파일 있을 때
- 기존 첨부파일이 있을 경우 : ATTACHMENT테이블 UPDATE요청
- 기존 첨부파일이 없을 경우 : ATTACHMENT테이블 INSERT요청
public int updateBoard(Board b, Attachment at) {
Connection conn = getConnection();
// BOARD테이블 작업
int result1 = new BoardDao().updateBoard(conn, b);
// ATTACHMENT테이블 작업
int result2 = 1;
// 새롭게 첨부파일이 있을 경우
if(at != null) {
if(at.getFileNo() != 0) { // 기존 첨부파일이 있었을 경우
result2 = new BoardDao().updateAttachment(conn, at);
} else { // 없었을 경우
result2 = new BoardDao().insertNewAttachment(conn, at);
}
} // 아닐 경우 첨부파일 관련작업 하지 않아도 됨 -> else구문X
// 둘 다 성공했을 경우에만 commit
if((result1 * result2) > 0) commit(conn);
else rollback(conn);
close(conn);
return (result1 * result2);
}
3. BoardDao.java (자바클래스)
- 세 개의 메소드 작성
- updateBoard() : 게시글 수정을 위해 무조건 실행하는 SQL문 작동
public int updateBoard(Connection conn, Board b) {
int result = 0;
PreparedStatement pstmt = null;
String sql = prop.getProperty("updateBoard");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, Integer.parseInt(b.getCategory()));
pstmt.setString(2, b.getBoardTitle());
pstmt.setString(3, b.getBoardContent());
pstmt.setInt(4, b.getBoardNo());
result = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(pstmt);
}
return result;
}
- SQL문 (UPDATE)
<entry key="updateBoard">
UPDATE
BOARD
SET
CATEGORY_NO = ?,
BOARD_TITLE = ?,
BOARD_CONTENT =?
WHERE
BOARD_NO = ?
</entry>
- updateAttachment() : 기존 첨부파일이 있는 경우
public int updateAttachment(Connection conn, Attachment at) {
int result = 0;
PreparedStatement pstmt = null;
String sql = prop.getProperty("updateAttachment");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, at.getOriginName());
pstmt.setString(2, at.getChangeName());
pstmt.setString(3, at.getFilePath());
pstmt.setInt(4, at.getFileNo());
result = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(pstmt);
}
return result;
}
- SQL문 (UPDATE)
<entry key="updateAttachment">
UPDATE
ATTACHMENT
SET
ORIGIN_NAME = ?,
CHANGE_NAME = ?,
FILE_PATH = ?,
UPLOAD_DATE = SYSDATE
WHERE
FILE_NO = ?
</entry>
- insertNewAttachment() : 기존 첨부파일이 없을 경우
public int insertNewAttachment(Connection conn, Attachment at) {
int result = 0;
PreparedStatement pstmt = null;
String sql = prop.getProperty("insertNewAttachment");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, at.getRefBno());
pstmt.setString(2, at.getOriginName());
pstmt.setString(3, at.getChangeName());
pstmt.setString(4, at.getFilePath());
result = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(pstmt);
}
return result;
}
- SQL문 (INSERT)
<entry key="insertNewAttachment">
INSERT
INTO
ATTACHMENT
(
FILE_NO,
REF_BNO,
ORIGIN_NAME,
CHANGE_NAME,
FILE_PATH
)
VALUES
(
SEQ_FNO.NEXTVAL,
?,
?,
?,
?
)
</entry>
'개발 > Web' 카테고리의 다른 글
[Java] JSP - JSP 내장객체 / EL구문 (Expression Language) (0) | 2022.12.13 |
---|---|
[Java] Servlet - Request / Session / Application / Page 객체 (0) | 2022.11.18 |
[Java] Sevlet/JSP - 일반게시판 - 게시글 작성 (첨부파일 1개 업로드) (0) | 2022.11.18 |
[Java] Sevlet/JSP - 일반게시판 - 게시글 리스트 조회 / 페이징 처리 (0) | 2022.11.18 |
[Java] Sevlet/JSP - 공지사항 - 공지사항 리스트 조회 (0) | 2022.11.18 |