교재 실습/자바 웹 개발 워크북

98. 실력 향상 훈련 (4)

Jint 2022. 8. 23. 00:30

5. 훈련 3 프로젝트 변경 구현

세 번째 훈련은 프로젝트 변경을 구현하는 것이다.

 

1) DAO 인터페이스에 변경 메서드 추가

ProjectDao 인터페이스에 프로젝트 데이터를 찾거나 변경할 때 호출할 메서드를 선언한다. 다음은 추가할 메서드이다.

Project selectOne(int no) throws Exception; //프로젝트 상세정보 조회 메서드
int update(Project project) throws Exception; //프로젝트 데이터 변경 메서드

 

2) DAO 구현체에 메서드 추가

ProjectDao 인터페이스의 변경에 맞추어 MySqlProjectDao 클래스에 메서드를 추가한다. selectOne() 메서드는 프로젝트 번호에 해당하는 데이터를 찾아서 반환한다. update() 메서드는 기존 프로젝트 정보를 사용자가 입력한 값으로 변경한다. 변경할 컬럼은 프로젝트 이름(PNAME), 내용(CONTENT), 시작일(STA_DATE), 종료일(END_DATE), 상태(STATE), 태그(TAGS) 이다.

 

3) 페이지 컨트롤러 생성

spms.controls 패키지에 ProjectUpdateController 클래스를 생성한다. GET 요청이 들어오면 MySqlProjectDao 객체를 통해 프로젝트 정보를 가져온다. 그리고 /project/ProjectUpdateForm.jsp로 보낸다. POST 요청이 들어오면 프로젝트 데이터를 변경하고 나서, 다시 프로젝트 변경폼으로 리다이렉트 한다.

 

4) JSP 페이지 생성

프로젝트 목록에서 프로젝트 제목을 클릭하면 상세 정보를 출력해야 한다. 프로젝트의 상세 정보를 출력할 JSP(webapp/project/ProjectUpdateForm.jsp)를 생성한다. 이때 상세 정보 페이지에서 데이터를 바로 변경할 수 있도록, 프로젝트 입력폼처럼 <form> 태그를 사용한다(그림 1).

그림 1 (프로젝트 변경폼)

 

- 훈련 3 결과 소스

세 번째 훈련의 결과 소스이다.

소스 파일 설명
spms/dao/ProjectDao.java ProjectDao 인터페이스에 selectOne(), update() 메서드 추가
spms/dao/MySqlProjectDao.java selectOne(), update() 메서드 구현
spms/controls/ProjectUpdateController.java 프로젝트의 변경을 처리하는 페이지 컨트롤러
webapp/project/ProjectUpdateForm.jsp 프로젝트 변경폼을 생성하는 뷰 컴포넌트

 

- DAO 인터페이스 - ProjectDao

package spms.dao;

import java.util.List;

import spms.vo.Project;

//ProjectDao 인터페이스 정의
public interface ProjectDao {
	List<Project> selectList() throws Exception; //프로젝트 목록 반환 메서드
	int insert(Project project) throws Exception; //프로젝트 데이터 등록 메서드
	Project selectOne(int no) throws Exception; //프로젝트 상세정보 조회 메서드
	int update(Project project) throws Exception; //프로젝트 데이터 변경 메서드
}

 

- DAO 구현체 - MySqlProjectDao

package spms.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import spms.annotation.Component;
import spms.vo.Project;

@Component("projectDao")
public class MySqlProjectDao implements ProjectDao {
	
	...

	//프로젝트 상세정보 조회
	@Override
	public Project selectOne(int no) throws Exception {
		Connection connection = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			connection = ds.getConnection(); //커넥션 객체 가져오기
			stmt = connection.createStatement();
			rs = stmt.executeQuery(
				"SELECT PNO, PNAME, CONTENT, STA_DATE, END_DATE, STATE, CRE_DATE, TAGS "
			  + "FROM PROJECTS "
			  + "WHERE PNO=" + no);
			if(rs.next()) {
				return new Project().setNo(rs.getInt("PNO"))
									.setTitle(rs.getString("PNAME"))
									.setContent(rs.getString("CONTENT"))
									.setStartDate(rs.getDate("STA_DATE"))
									.setEndDate(rs.getDate("END_DATE"))
									.setState(rs.getInt("STATE"))
									.setCreatedDate(rs.getDate("CRE_DATE"))
									.setTags(rs.getString("TAGS"));
			}else {
				throw new Exception("해당 번호의 프로젝트를 찾을 수 없습니다.");
			}
		} catch (Exception e) {
			throw e;
		} finally {
			try {if (rs != null) rs.close();} catch(Exception e) {}
			try {if (stmt != null) stmt.close();} catch(Exception e) {}
			try {if(connection != null) connection.close();} catch(Exception e) {}
		}
	}

	//프로젝트 수정
	@Override
	public int update(Project project) throws Exception {
		Connection connection = null;
		PreparedStatement stmt = null;
		try {
			connection = ds.getConnection(); //커넥션 객체 가져오기
			stmt = connection.prepareStatement(
				"UPDATE PROJECTS SET PNAME=?, CONTENT=?, STA_DATE=?, END_DATE=?, STATE=?, TAGS=? "
			  + "WHERE PNO=?");
			stmt.setString(1, project.getTitle());
			stmt.setString(2, project.getContent());
			stmt.setDate(3, new java.sql.Date(project.getStartDate().getTime()));
			stmt.setDate(4, new java.sql.Date(project.getEndDate().getTime()));
			stmt.setInt(5, project.getState());
			stmt.setString(6, project.getTags());
			stmt.setInt(7, project.getNo());
			return stmt.executeUpdate();
		} catch (Exception e) {
			throw e;
		} finally {
			try {if (stmt != null) stmt.close();} catch(Exception e) {}
			try {if(connection != null) connection.close();} catch(Exception e) {}
		}
	}
	
}

 

- 페이지 컨트롤러 - ProjectUpdateController

package spms.controls;

import java.util.Map;

import spms.annotation.Component;
import spms.bind.DataBinding;
import spms.dao.MySqlProjectDao;
import spms.vo.Project;

@Component("/project/update.do")
public class ProjectUpdateController implements Controller, DataBinding {
	
	//인스턴스 변수
	MySqlProjectDao projectDao;
	
	//셋터 메서드
	public ProjectUpdateController setProjectDao(MySqlProjectDao projectDao) {
		this.projectDao = projectDao;
		return this;
	}
	
	//DataBinding 인터페이스의 구현 메서드
	@Override
	public Object[] getDataBinders() {
		return new Object[] {"no", Integer.class, "project", spms.vo.Project.class};
	}

	//Controller 인터페이스 구현 메서드
	@Override
	public String execute(Map<String, Object> model) throws Exception {
		//프런트 컨트롤러가 VO 객체를 무조건 생성할 것이기 때문에 Project 객체 여부로 판단하지 않는다.
		Project project = (Project)model.get("project");
		if(project.getTitle() == null) {//입력폼을 요청할 때
			Integer no = (Integer)model.get("no");
			Project detailInfo = projectDao.selectOne(no);
			model.put("project", detailInfo);
			return "/project/ProjectUpdateForm.jsp";
		}else {//프로젝트 수정을 요청할 때
			projectDao.update(project);
			return "redirect:list.do";
		}
	}

}

 

- 뷰 컴포넌트 - ProjectUpdateForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>프로젝트 정보</title>
<style>
ul {padding: 0;}
li {list-style: none;}
label {
	float: left;
	text-align: right;
	width: 60px;
}
</style>
</head>
<body>
<jsp:include page="/Header.jsp"/>
<h1>프로젝트 정보</h1>
<form action='update.do' method='post'>
	<ul>
		<li>
			<label for="no">번호</label> 
  			<input id="no" type='text' name='no' size="5" value="${project.no}" readonly>
  		</li>
		<li>
			<label for="title">제목</label> 
			<input id="title" type='text' name='title' size="50" value="${project.title}">
		</li>
		<li>
			<label for="content">내용</label>
			<textarea id="content" name='content' rows="5" cols="40">${project.content}</textarea>
		</li>
		<li>
			<label for="sdate">시작일</label>
			<input id="sdate" type='text' name='startDate' placeholder="예) 2022-01-01" value="${project.startDate}">
		</li>
		<li>
			<label for="edate">종료일</label>
			<input id="edate" type='text' name='endDate' placeholder="예) 2022-01-01" value="${project.endDate}">
		</li>
		<li>
			<label for="state">상태</label>
			<select id="state" name="state">
				<option value="0" ${project.state == 0 ? "selected" : ""}>준비</option>
				<option value="1" ${project.state == 1 ? "selected" : ""}>진행</option>
				<option value="2" ${project.state == 2 ? "selected" : ""}>완료</option>
				<option value="3" ${project.state == 3 ? "selected" : ""}>취소</option>
			</select>
		</li>
		<li>
			<label for="tags">태그</label>
			<input id="tags" type='text' name='tags' placeholder="예) 태그1 태그2 태그3" size="50" value="${project.tags}">
		</li>
	</ul>
	<input type='submit' value='저장'>
	<input type='button' value='삭제' onclick='location.href="delete.do?no=${project.no}";'>
	<input type='button' value='취소' onclick='location.href="list.do"'>
</form>
<jsp:include page="/Tail.jsp"/>
</body>
</html>

 

참고도서 : https://freelec.co.kr/book/1674/

 

[열혈강의] 자바 웹 개발 워크북

[열혈강의] 자바 웹 개발 워크북

freelec.co.kr