오늘의 코딩순서
(폴더: 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 value와 Sequence
- Max value
- 주어진 컬럼의 최대 값을 반환하며, 주로 집계 함수로 사용됨
- 중복을 직접 방지하는 기능은 없지만, 데이터 삽입 전에 최대 값을 확인하여 중복된 데이터가 존재하는지 확인하거나 고유 값을 생성하는 데 도움이 될 수 있음
- Sequence
- 고유한 숫자 시퀀스를 생성하고 관리하는 객체
- 주로 고유한 식별자(ID)를 생성할 때 사용되며, 시퀀스는 특정 시작 값부터 시작하여 증가(또는 감소)하는 숫자 시퀀스를 제공함
- 데이터베이스에서 고유한 값을 자동으로 생성하기 때문에 중복을 방지하는 데 매우 유용함
- 시퀀스는 값이 자동으로 증가하여 새로운 행을 삽입할 때 중복되지 않도록 보장함
- 주로 기본 키(Primary Key)나 고유 키(Unique Key)와 같이 유일해야 하는 값들을 생성하는 데 사용됨
- Max value와 Sequence의 조합
- 두 기능을 조합하여 중복을 더 효과적으로 방지할 수 있음
ex) 시퀀스를 사용하여 고유한 값을 생성하고, 시퀀스의 시작 값을 테이블의 최대 값으로 설정하면 기존 테이블의 최대 값 이후부터 시퀀스가 시작되어 중복되지 않는 값을 안전하게 생성할 수 있음
- 두 기능을 조합하여 중복을 더 효과적으로 방지할 수 있음
- Max value
- if(num == 0) board.setRef(number); 의 기능
: num이 0이면 새 글이므로 board 객체의 ref 속성을 새로 생성된 number로 설정
여기서 ref는 주로 답글 기능이 있는 게시판에서 원글과 답글을 그룹화하는 데 사용
- int num = board.getNum(); 의 기능
//(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의 값을 더함으로서, 가장 최근에 작성한 댓글이 가장 위로 올라올 수 있도록 함
- String sql2 = "update board set re_step = re_step+1 where ref=? and re_step > ?";
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 |