본문 바로가기
JSP/Java Script

2024_07_26_금

by 알케니브 2024. 7. 26.

오늘의 코딩순서

(폴더: och16)

메인 페이지 ↓↓↓

http://localhost:8181/och16/list.do

  • command.properties.file
  • UpdateFormAction.class (현장 HW1-1) + updateForm.jsp + UpdateProAction.class (현장 HW1-2) 
    + updatePro.jsp + BoardDao.class (현장 HW 1-3)
  • WriterFormAction.class + writeForm.jsp + WriterProAction.class (현장 HW 2-1) + writerPro.jsp +  BoardDao.class (현장 HW 2-2)
  • WriterFormAction.class 에서 댓글 로직 추가 + BoardDao.class 

오늘의 코딩 포인트

  • command.properties.file
/list.do=service.ListAction
/content.do=service.ContentAction
/updateForm.do=service.UpdateFormAction
/updatePro.do=service.UpdateProAction
/writeForm.do=service.WriterFormAction
/writePro.do=service.WriterProAction


  • UpdateFormAction.class (현장 HW1-1)  ==> Service 모델
package service;

import java.io.IOException;
import java.sql.SQLException;

import dao.Board;
import dao.BoardDao;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class UpdateFormAction implements CommandProcess {

	@Override
	public String requestPro(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("UpdateFormAction start..");
	//(0726)현장 HW 1-1
		// 1. num , pageNum  GET
		int num = Integer.parseInt(request.getParameter("num"));
		String pageNum = request.getParameter("pageNum");
		
		try {
			// 2. BoardDao bd Instance	
			BoardDao bd = BoardDao.getInstance();
			// 3. Board board = bd.select(num);
			Board board = bd.select(num);
            	//num으로 DTO값 넣기
			// 4. request 객체에 pageNum , board
			request.setAttribute("pageNum", pageNum);
			request.setAttribute("board", board);
		
		} catch (SQLException e) {
			System.out.println("UpdateFormAction e.getMessage()->"+e.getMessage());
		}
		return "updateForm.jsp";
	}

}
  • updateForm.jsp 
    Tip) content를 input로 바꿔주는 방식
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판 수정</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
	<form action="updatePro.do" method="post">
		<input type="hidden" name="num" value="${board.num}">
		<input type="hidden" name="pageNum" value="${pageNum}">
		<table>
			<caption>게시판 수정</caption>
			<tr><td>번호</td>	<td>${board.num}</td></tr>
			<tr><td>제목</td>
				<td><input type="text" name="subject" required="required"
									value="${board.subject}"></td></tr>
			<tr><td>작성자</td>
				<td><input type="text" name="writer" required="required"
									value="${board.writer}"></td></tr>
			<tr><td>이메일</td>
				<td><input type="email" name="email" required="required"
									value="${board.email}"></td></tr>
			<tr><td>암호</td>
				<td><input type="password" name="passwd" required="required"
									value="${board.passwd}"></td></tr>
			<tr><td>아이피</td>
				<td><input type="text" name="ip" required="required"
									value="${board.ip}"></td></tr>
			<tr><td>내용</td>
				<td><pre><textarea rows="10" cols="40" name="content" 
									required="required">${board.content}
						</textarea></pre></td></tr>
			<tr><td colspan="2"><input type="submit" value="수정완료"></td></tr>
	
		</table>
	</form>
</body>
</html>

  • UpdateProAction.class ==> Service 모델 (현장 HW 1-2)
package service;

import java.io.IOException;
import java.sql.SQLException;

import dao.Board;
import dao.BoardDao;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class UpdateProAction implements CommandProcess {

	@Override
	public String requestPro(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("UpdateProAction start...");
	//(0726)현장 HW 1-2
		// 1. num , pageNum, writer ,  email , subject , passwd , content   Get
		int num = Integer.parseInt(request.getParameter("num"));
		String pageNum = request.getParameter("pageNum");
		String writer = request.getParameter("writer");
		String email = request.getParameter("email");
		String subject = request.getParameter("subject");
		String passwd = request.getParameter("passwd");
		String content = request.getParameter("content");
		String ip = request.getParameter("ip");

		try {
			// 2. Board board 생성하고 Value Setting
           			//DTO 단위의 작업
			Board board = new Board();
			board.setNum(num);
			board.setWriter(writer);
			board.setEmail(email);
			board.setSubject(subject);
			board.setPasswd(passwd);
			board.setContent(content);
			board.setIp(ip);
			/* try 위에 쓰지 않았다면, 아래의 방식으로 request를 작성해야한다, 다만 한 가지 방법만 쓸 것
			board.setNum(Integer.parseInt(request.getParameter("num")));
			board.setWriter(writer);
			board.setEmail(request.getParameter("email"));*/

			// 3. BoardDao bd Instance
			BoardDao bd = BoardDao.getInstance();
			int result = bd.update(board);
			
			// 4. request 객체에 result, num , pageNum 
			//아래처럼 다양한 이름이 가능함
			request.setAttribute("result", result);
			request.setAttribute("num", board.getNum());
			request.setAttribute("pageNum", pageNum);
			
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
			
	    // 5.updatePro.jsp Return
		return "updatePro.jsp";
	}

}
  • updatePro.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<c:if test="${result > 0}">
		<script type="text/javascript">
			alert("수정 완료 ! ");
			location.href = "list.do?pageNum=${pageNum}";
		</script>
	</c:if>
	<c:if test="${result == 0}">
		<script type="text/javascript">
			alert("수정 안 됐어요T.T");
			location.href = "updateForm.do?num=${num}&pageNum=${pageNum}";
		</script>
	</c:if>	
</body>
</html>
  • BoardDao.class (현장 HW 1-3) =>update.jsp와 연결됨
//(0726)현장 HW 1-3 =>updateForm.jsp와 연결됨
	public int update(Board board) throws SQLException {
		int result = 0;
		Connection conn = null;
		PreparedStatement pstmt = null;
		
		System.out.println("getNum->"+board.getNum());
		System.out.println("getSubject->"+board.getSubject());
		System.out.println("getWriter->"+board.getWriter());
		System.out.println("getEmail->"+board.getEmail());
		System.out.println("getPasswd->"+board.getPasswd());
		System.out.println("getContent->"+board.getContent());
		
		String sql = "update board set subject=?, writer=?, email=?, passwd=?, "
					+ "content=?, ip=? where num=?";
				
		
		try {
			conn = getConnection();
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, board.getSubject());
			pstmt.setString(2, board.getWriter());
			pstmt.setString(3, board.getEmail());
			pstmt.setString(4, board.getPasswd());
			pstmt.setString(5, board.getContent());
			pstmt.setString(6, board.getIp());
			pstmt.setInt(7, board.getNum());
			
			result = pstmt.executeUpdate();
			System.out.println("result->"+result);
			
		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			if (pstmt != null)	pstmt.close();
			if (conn != null)	conn.close();
		}
		return result;
	}


  • WriterFormAction.class
package service;

import java.io.IOException;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class WriterFormAction implements CommandProcess {

	@Override
	public String requestPro(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("WriteFormAction start...");
		
		try {
			//신규글
			int num = 0, ref = 0, re_level = 0, re_step = 0;
			String pageNum = request.getParameter("pageNum");
			if (pageNum == null) pageNum="1";
			
			request.setAttribute("num", num);
			request.setAttribute("ref", ref);
			request.setAttribute("re_level", re_level);
			request.setAttribute("re_step", re_step);
			request.setAttribute("pageNum", pageNum);
		
		} catch (Exception e) {
			System.out.println("WriterFormAction e.getMessage->"+e.getMessage());
		}
		return "writeForm.jsp";
	}

}
  • writeForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<title>글작성</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
	<form action="writePro.do?pageNum=${pageNum}" method="post">
		<!-- 아래 네 줄은 원글에 관련된 값 -->
		<input type="hidden" name="num"			value="${num}">
		<input type="hidden" name="ref"			value="${ref}">
		<input type="hidden" name="re_level"	value="${re_level}">
		<input type="hidden" name="re_step"		value="${re_step}">
		<table>
			<caption><h2>게시판 글쓰기</h2></caption>
			<tr><td>제목</td>
				<!-- 댓글 -->
			<td><c:if test="${num > 0}">
				<input type="text" name="subject" value="[답변]" required="required">
				</c:if>
				<!-- 최초 글쓰기 -->
				<c:if test="${num == 0}">
				<input type="text" name="subject" required="required">
				</c:if></td></tr>
			<tr><td>작성자</td><td><input type="text" name="writer"	required="required"></td></tr>
			<tr><td>이메일</td><td><input type="email" name="email"	required="required"></td></tr>
			<tr><td>내용</td><td><textarea rows="10" cols="30" name="content"
											required="required"></textarea></td></tr>
			<tr><td>암호</td><td><input type="password" name="passwd"	required="required"></td></tr>
			<tr><td><input type="submit" value="확인"></td>
				<td><input type="reset" value="다시작성"></td></tr>
		
		</table>
	</form>
</body>
</html>
  • WriterProAction.class (현장 HW 2-1)
package service;

import java.io.IOException;

import dao.Board;
import dao.BoardDao;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class WriterProAction implements CommandProcess {

	@Override
	public String requestPro(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("WriteProAction start...");
		
		//(0726)현장 HW 2-1
		try {
		// 1. num , pageNum, writer ,  email , subject , passwd , content   Get
		// 2. Board board 생성하고 Value Setting
			String pageNum = request.getParameter("pageNum");
			Board board = new Board();
			board.setNum(Integer.parseInt(request.getParameter("num")));
			board.setWriter(request.getParameter("writer"));
			board.setEmail(request.getParameter("email"));
			board.setSubject(request.getParameter("subject"));
			board.setPasswd(request.getParameter("passwd"));
			board.setRef(Integer.parseInt(request.getParameter("ref")));

			board.setRe_step(Integer.parseInt(request.getParameter("re_step")));
			board.setRe_level(Integer.parseInt(request.getParameter("re_level")));
			board.setContent(request.getParameter("content"));
			board.setIp(request.getRemoteAddr());
			
			// 3. BoardDao bd Instance
			BoardDao bd = BoardDao.getInstance();
			// 4. request 객체에 result, num , pageNum
			int result = bd.insert(board);
			request.setAttribute("result", result);
			request.setAttribute("num", board.getNum());
			request.setAttribute("pageNum", pageNum);
			
		} catch (Exception e) {
			System.out.println("WriterProAction e.getMessage()->"+e.getMessage());
		}
		return "writePro.jsp";
	}

}
  • writerPro.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<c:if test="${result > 0 }">
		<script type="text/javascript">
			alert("입력 완료 ^^");
			location.href="list.do?pageNum=${pageNum}";
		</script>
	</c:if>
	<c:if test="${result == 0}">
		<script type="text/javascript">
			alert("오류야T.T");
			location.href="writeForm.do?num=${num}&pageNum=${pageNum}";
		</script>
	</c:if>
</body>
</html>
  • BoardDao.class (현장 HW 2-2)
    Tip)
    • int num = board.getNum(); 의 기능
      : 
      Board 객체에서 num이라는 속성의 값을 가져오는 역할을 함
      게시판에서는 Board 객체에서 현재 글의 num 값을 가져와서 새 글인지 기존 글인지 확인하는 데 사용됨
      만약 새 글이라면, 데이터베이스에서 가장 큰 num 값을 찾아서 그보다 1 큰 값을 새 글의 num으로 설정하며, 이를 통해 데이터베이스의 num 값이 고유하게 유지되도록 함
    • select nvl(max(num),0) 의 기능
      • max(num): max 함수는 주어진 열의 최대값을 반환함. 따라서 'num'열에서 가장 큰 값을 반환함
      • nvl(max(num), 0): nvl 함수는 괄호 안의 첫 번째 인수(여기서는 max(num))가 NULL인 경우, 두 번째 인수(여기서는 0)을 반환함
      •  board TBL의 num값들이 존재한다면 가장 큰 값을 반환하며, board TBL에 레코드가 하나도 없어서 num 값이 존재하지 않으면 max(num)이 NULL을 반환함. 이 경우 nvl함수가 NULL 대신 0을 반환하도록 함
    • int number = rs.getInt(1) + 1; 의 기능
      : rs.getInt(1)은 ResultSet 객체 rs의 첫 번째 열(column)에서 정수 값을 가져옴
      sql1 쿼리( select nvl(max(num),0) from board)의 결과로 가장 큰 num 값을 가져오며, 만약 테이블에 레코드가 하나도 없을 경우, nvl(max(num),0)는 0을 반환함
      이렇게 가져온 값에 +1을 하고 그 값은 number 변수에 저장되며, 이 변수의 값은 새로 삽입될 글의 num 값이 됨
      즉, 이 코드는 새로 삽입될 레코드의 num 값을 현재 테이블에서 가장 큰 num 값보다 1 크게 설정하여 고유성을 유지하도록 함
       고유성을 유지하는 이유는 num이 primary key 역할을 하기 때문에 NUll 값을 가지면 오류가 날 수 있기 때문
      또한 데이터의 무결성을 유지하고, 각 레코드를 고유하게 식별할 수 있게 함
    • 중복 키워드와 관련된 SQL의 Max valueSequence
      • Max value
        • 주어진 컬럼의 최대 값을 반환하며, 주로 집계 함수로 사용됨
        • 중복을 직접 방지하는 기능은 없지만, 데이터 삽입 전에 최대 값을 확인하여 중복된 데이터가 존재하는지 확인하거나 고유 값을 생성하는 데 도움이 될 수 있음
      • Sequence
        • 고유한 숫자 시퀀스를 생성하고 관리하는 객체
        • 주로 고유한 식별자(ID)를 생성할 때 사용되며, 시퀀스는 특정 시작 값부터 시작하여 증가(또는 감소)하는 숫자 시퀀스를 제공함
        • 데이터베이스에서 고유한 값을 자동으로 생성하기 때문에 중복을 방지하는 데 매우 유용함
        • 시퀀스는 값이 자동으로 증가하여 새로운 행을 삽입할 때 중복되지 않도록 보장함
        • 주로 기본 키(Primary Key)나 고유 키(Unique Key)와 같이 유일해야 하는 값들을 생성하는 데 사용됨
      • Max value와 Sequence의 조합
        • 두 기능을 조합하여 중복을 더 효과적으로 방지할 수 있음
          ex) 시퀀스를 사용하여 고유한 값을 생성하고, 시퀀스의 시작 값을 테이블의 최대 값으로 설정하면 기존 테이블의 최대 값 이후부터 시퀀스가 시작되어 중복되지 않는 값을 안전하게 생성할 수 있음
    • if(num == 0) board.setRef(number); 의 기능
      : num이 0이면 새 글이므로 board 객체의 ref 속성을 새로 생성된 number로 설정
      여기서 ref는 주로 답글 기능이 있는 게시판에서 원글과 답글을 그룹화하는 데 사용
//(0726)현장 HW 2-3 =>writeForm.jsp와 연결됨
	public int insert(Board board) throws SQLException {
		System.out.println("DAO insert start...");
		int num = board.getNum();
		int result = 0;
		ResultSet rs=null;
		Connection conn = null;
		PreparedStatement pstmt = null;
		String sql1 = "select nvl(max(num),0) from board";
		String sql3="insert into board values(?,?,?,?,?,?,?,?,?,?,?,sysdate)";
		
		try {
			conn = getConnection();
			pstmt = conn.prepareStatement(sql1);
			rs = pstmt.executeQuery();
			rs.next();
			
			// key인 num 1씩 증가, my sql auto_increment 또는 oracle sequence
			//sequence를 사용 : values(시퀸스명(board_seq).nextval,?,?...)
			int number = rs.getInt(1) +1;
			rs.close();
			pstmt.close();
			
			if(num == 0) board.setRef(number);
			//아래는 if 하위 로직이 아니기 때문에 들여쓰기 하면 안됨!
			pstmt = conn.prepareStatement(sql3);
			pstmt.setInt(1, number);
			pstmt.setString(2, board.getWriter());
			pstmt.setString(3, board.getSubject());
			pstmt.setString(4, board.getContent());
			pstmt.setString(5, board.getEmail());
			pstmt.setInt(6, board.getReadcount());
			pstmt.setString(7, board.getPasswd());
			pstmt.setInt(8, board.getRef());
			pstmt.setInt(9, board.getRe_step());
			pstmt.setInt(10, board.getRe_level());
			pstmt.setString(11, board.getIp());
			result = pstmt.executeUpdate();

		} catch (Exception e) {
			System.out.println("DAO insert e.getMessage()->"+e.getMessage());
		} finally {
			if (rs != null)			rs.close();
			if (pstmt != null)		pstmt.close();
			if (conn != null)		conn.close();
		}
		return result;
	}

신규 글 작성
작성 후 게시글


  • WriterFormAction.class 에서 댓글 로직 추가
package service;

import java.io.IOException;

import dao.Board;
import dao.BoardDao;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class WriterFormAction implements CommandProcess {

	@Override
	public String requestPro(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("WriteFormAction start...");
		
		try {
			//신규글
			int num = 0, ref = 0, re_level = 0, re_step = 0;
			String pageNum = request.getParameter("pageNum");
			if (pageNum == null) pageNum = "1";
			
			//댓글일 경우
			if (request.getParameter("num")	!= null) {
				num = Integer.parseInt(request.getParameter("num"));
				BoardDao bd = BoardDao.getInstance();
				Board board = bd.select(num);
				ref = board.getRef();
				re_level = board.getRe_level();
				re_step = board.getRe_step();
			}
			
			request.setAttribute("num", num);
			request.setAttribute("ref", ref);
			request.setAttribute("re_level", re_level);
			request.setAttribute("re_step", re_step);
			request.setAttribute("pageNum", pageNum);
		
		} catch (Exception e) {
			System.out.println("WriterFormAction e.getMessage->"+e.getMessage());
		}
		return "writeForm.jsp";
	}

}
  • BoardDao.class
    Tip)
    • String sql2 = "update board set re_step = re_step+1 where ref=? and re_step > ?";
      :
      +1의 값을 더함으로서, 가장 최근에 작성한 댓글이 가장 위로 올라올 수 있도록 함
	public int insert(Board board) throws SQLException {
		System.out.println("DAO insert start...");
		int num = board.getNum();
		int result = 0;
		ResultSet rs=null;
		Connection conn = null;
		PreparedStatement pstmt = null;
		String sql1 = "select nvl(max(num),0) from board";
		String sql2 = "update board set re_step = re_step+1 where ref=? and re_step > ?";
		String sql3="insert into board values(?,?,?,?,?,?,?,?,?,?,?,sysdate)";
		
		
		try {
			//sql1: 새 글을 입력하기 위해 num(primary key)를 가져오기 위한 로직
			conn = getConnection();
			pstmt = conn.prepareStatement(sql1);
			rs = pstmt.executeQuery();
			rs.next();
			
			// key인 num 1씩 증가, my sql auto_increment 또는 oracle sequence
			//sequence를 사용 : values(시퀸스명(board_seq).nextval,?,?...)
			int number = rs.getInt(1) +1;
			rs.close();
			pstmt.close();
			
			//sql2: 신규 글 + 댓글 추가 공용된 로직 
			// 이를 추가한 이유는 최근에 작성한 댓글이 제일 위로 올라오도록 하기 위해
			if (num != 0) {
				System.out.println("BoardDAO insert 댓글 sql2->"+sql2);
				System.out.println("BoardDAO insert 댓글 board.getRef()->"+board.getRef());
				System.out.println("BoardDAO insert 댓글 board.getRe_step->"+board.getRe_step());
				
				pstmt = conn.prepareStatement(sql2);
				pstmt.setInt(1, board.getRef());
				pstmt.setInt(2, board.getRe_step());
				pstmt.executeUpdate();
				pstmt.close();
				
				// 댓글 관련 정보: ref+1한 값= re_step와 re_level이 된다 
				board.setRe_step(board.getRe_step()+1);
				board.setRe_level(board.getRe_level()+1);
			}
			System.out.println("BoardDAO insert num->"+num);
			System.out.println("BoardDAO insert number->"+number);

			
			//sql3: //신규 글 작성
			if(num == 0) board.setRef(number);
			// 신규글과 댓글의 number을 비교하는 로직
			//신규글은 board num이랑 ref의 num이 같음
			
			// 여기부터는 if 하위 로직이 아니기 때문에 들여쓰기 하면 안됨!
			pstmt = conn.prepareStatement(sql3);
			pstmt.setInt(1, number);
			pstmt.setString(2, board.getWriter());
			pstmt.setString(3, board.getSubject());
			pstmt.setString(4, board.getContent());
			pstmt.setString(5, board.getEmail());
			pstmt.setInt(6, board.getReadcount());
			pstmt.setString(7, board.getPasswd());
			pstmt.setInt(8, board.getRef());
			pstmt.setInt(9, board.getRe_step());
			pstmt.setInt(10, board.getRe_level());
			pstmt.setString(11, board.getIp());
			result = pstmt.executeUpdate();

		} catch (Exception e) {
			System.out.println("DAO insert e.getMessage()->"+e.getMessage());
		} finally {
			if (rs != null)			rs.close();
			if (pstmt != null)		pstmt.close();
			if (conn != null)		conn.close();
		}
		return result;
	}
}

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 


질문목록

 


수업교재

 

 


오늘의 숙제

'JSP > Java Script' 카테고리의 다른 글

2024_07_25_목  (0) 2024.07.26
2024_07_24_수  (0) 2024.07.24
2024_07_23_화~ 07_24_수  (0) 2024.07.23
2024_07_22_월  (0) 2024.07.22
2024_07_19_금 ⭐⭐⭐  (0) 2024.07.19