삶 가운데 남긴 기록 AACII.TISTORY.COM
CRUD 본문
CRUD
웹 어플리케이션은 서버의 자원을 Create, Read, Update, Delete 하도록 서비스를 구성하는데 이를 줄여서 CRUD라고 합니다.
예를들어 회원 가입(Create), 회원정보조회(Read), 회원정보수정(Update), 회원정보삭제(Delete) 를 한 세트로 묶어서 회원정보에 대한 서버 자원(DB)에 대한 서비스를 구현합니다.
이전 jsp프로젝트 처럼 새 Dynamic Web Project를 생성하여 예제를 구현해보도록 합시다.
tomcat의 context path는 / 으로 지정합니다.
프로젝트 생성시 web.xml 생성 옵션을 체크합니다.
프로젝트 src 경로에 controller, dao, service, vo 패키지를 생성합니다.
그리고 .do 요청을 처리하기 위해 프론트 컨트롤러를 만들고 URL을 연결합니다.
데이터베이스(oracle) 준비
ojdbc 드라이버도 프로젝트 lib 폴더로 복사해둡니다.
데이터베이스는 기존에 세팅한 oracle을 사용합니다.
오라클DB 계정은 aacii/aacii 으로 작업한다고 가정하겠습니다.
SQL Developer 등으로 create 문을 작성해서 member 테이블을 생성합니다.
CREATE TABLE MEMBER(ID VARCHAR2(10) PRIMARY KEY, PASSWD VARCHAR2(10), NAME VARCHAR2(10), MAIL VARCHAR2(20));
프런트 컨트롤러 설정
WEB-INF 경로에 web.xml 를 편집합니다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>CRUD</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>front</servlet-name>
<servlet-class>controller.FrontController</servlet-class>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>front</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
모델(model) 객체 생성
vo 패키지에 Member.java 클래스를 작성합니다.
package vo;
public class MemberVO {
private String id;
private String passwd;
private String name;
private String mail;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
}
데이터베이스 처리 DAO
dao 패키지에 MemberDAO.java 클래스를 작성해서 DB 작업 처리를 합니다.
package dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import vo.MemberVO;
public class MemberDAO {
private static MemberDAO dao =new MemberDAO();
private MemberDAO() {
}
public static MemberDAO getInstance() {
return dao;
}
public Connection connect() {
Connection conn = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.6:1521:orcl","aacii","aacii");
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
public void close(Connection conn, PreparedStatement ps, ResultSet rs) {
if(rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
close(conn,ps);
}
public void close(Connection conn, PreparedStatement ps) {
if(ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public void memberInsert(MemberVO member) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = connect();
pstmt = conn.prepareStatement("insert into member values(?,?,?,?)");
pstmt.setString(1, member.getId());
pstmt.setString(2, member.getPasswd());
pstmt.setString(3, member.getName());
pstmt.setString(4, member.getMail());
pstmt.executeUpdate();
}catch (Exception e) {
e.printStackTrace();
}finally {
close(conn,pstmt);
}
}
}
컨트롤러(Controller) 생성
controller 패키지에 Controller.java 인터페이스를 생성합니다.
package controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//컨트롤러 인터페이스
public interface Controller {
public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
controller 패키지에 FrontController.java 를 작성합니다.
package controller;
import java.io.IOException;
import java.util.HashMap;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FrontController extends HttpServlet{
private static final long serialVersionUID = 1L;
String charset = null;
HashMap<String, Controller> list = null;
@Override
public void init(ServletConfig sc) throws ServletException{
charset = sc.getInitParameter("charset");
list = new HashMap<String, Controller>();
list.put("/memberInsert.do", new MemberInsertController());
//list.put("/memberSearch.do", new MemberSearchController());
//list.put("/memberUpdate.do", new MemberUpdateController());
//list.put("/memberDelete.do", new MemberDeleteController());
}
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
request.setCharacterEncoding(charset);
String url = request.getRequestURI();
String contextPath = request.getContextPath();
String path = url.substring(contextPath.length());
Controller subController = list.get(path);
subController.execute(request, response);
}
}
아직 MemberInsertController.java를 작성하지 않아 이클립스에서 에러 표기가 될 것입니다.
주석 처리한 것들은 이후 구현할 예정입니다.
controller 패키지에 HttpUtil.java 클래스를 작성합니다.
package controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HttpUtil {
public static void forward(HttpServletRequest request, HttpServletResponse response, String path) {
RequestDispatcher dispatcher = request.getRequestDispatcher(path);
try {
dispatcher.forward(request, response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
회원 가입을 위한 뷰(View) 생성(CREATE)
공통으로 쓸 페이지 home.jsp 에서 초기 화면인 인덱스 페이지 index.jsp로 포워딩 하는 기능을 구현해서 모든 페이이지 마다 공통으로 사용할 예정입니다.
WebContents 폴더 아래 result 폴더를 만들어서 home.jsp 작성합니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<a href="/index.jsp">첫 화면으로</a>"
WebContents 폴더에 회원 정보를 저장하는 memberInsert.jsp를 작성합니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Create</title>
</head>
<body>
<h3>회원 가입</h3>
${error}
<form action="memberInsert.do" method="post">
ID:<input type="text" name="id"><br>
PW:<input type="password" name="passwd"><br>
이름:<input type="text" name="name"><br>
Mail:<input type="text" name="mail"><br>
<input type="submit" value="가입">
</form>
</body>
</html>
Insert 요청을 처리하는 컨트롤러 작성
controller 패키지에 /memberInsert.do 요청을 처리하는 MemberInsertController.java를 작성합니다.
package controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import service.MemberService;
import vo.MemberVO;
public class MemberInsertController implements Controller{
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//request 객체에서 파라미터 추출
String id = request.getParameter("id");
String passwd = request.getParameter("passwd");
String name = request.getParameter("name");
String mail = request.getParameter("mail");
//유효성 체크
if(id.isEmpty() || passwd.isEmpty() || name.isEmpty() || mail.isEmpty()) {
request.setAttribute("error", "모든 항목을 빠짐없이 입력하세요");
HttpUtil.forward(request, response, "/memberInsert.jsp");
return;
}
//vo 객체에 데이터 바인딩
MemberVO member = new MemberVO();
member.setId(id);
member.setPasswd(passwd);
member.setName(name);
member.setMail(mail);
//서비스 객체의 메서드 호출
MemberService service = MemberService.getInstance();
service.memberInsert(member);
//결과 페이지로 이동
request.setAttribute("id", id);
HttpUtil.forward(request, response, "/result/memberInsertOutput.jsp");
}
}
서비스 처리
MemberInsertController에서 요청한 서비스를 처리하기 위해 service 패키지에 MemberService.java 를 작성합니다.
package service;
import dao.MemberDAO;
import vo.MemberVO;
public class MemberService {
private static MemberService service = new MemberService();
public MemberDAO dao = MemberDAO.getInstance();
private MemberService() {
}
public static MemberService getInstance() {
return service;
}
public void memberInsert(MemberVO member) {
dao.memberInsert(member);
}
}
결과 처리 페이지
WebContents 폴더에 result 폴더 아래 memberInsertOutput.jsp 파일을 작성합니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>생성 결과</title>
</head>
<body>
<h3> ${id} 님 가입이 완료되었습니다.</h3>
<%@ include file="home.jsp" %>
</body>
</html>
인덱스 페이지
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>인덱스 페이지</title>
</head>
<body>
첫 페이지
</body>
</html>
회원 정보 검색(READ)
WebContents 폴더에 memberSearch.jsp 를 생성합니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>READ</title>
</head>
<body>
<h3>회원정보 검색</h3>
${error}
<form action="memberSearch.do" method="post">
ID:<input type="test" name="id" />
<input type="hidden" name="job" value="search" />
<input type="submit" value="검색" />
</form>
</body>
</html>
FrontController.java 에서는 주석 해놓았던 부분의 주석을 풀어줍니다.
memberSearch.do 요청을 처리하기 위해 execute() 메소드를 구현한 컨트롤러 MemberSearchController.java를 controller 패키지에 생성합니다.
package controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import service.MemberService;
import vo.MemberVO;
public class MemberSearchController implements Controller {
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//Parameter 추출
String id = request.getParameter("id");
String job = request.getParameter("job");
String path = null;
if(job.equals("search")) {
path = "/memberSearch.jsp";
}else if(job.equals("update")) {
path = "/memberUpdate.jsp";
}else if(job.equals("delete")) {
path = "/memberDelete.jsp";
}
//유효성 체크
if(id.isEmpty()) {
request.setAttribute("error", "ID를 입력하십시오.");
HttpUtil.forward(request, response, path);
return;
}
//서비스 객체의 메소드 호출
MemberService service = MemberService.getInstance();
MemberVO member = service.memberSearch(id);
//Output view페이지로 이동
if(member == null) {
request.setAttribute("result", "검색된 결과가 없습니다.");
}
request.setAttribute("member", member);
if(job.equals("search")) {
path="/result/memberSearchOutput.jsp";
}
HttpUtil.forward(request, response, path);
}
}
서비스를 처리하기 위해 service 패키지에 MemberService.java 파일에 아래와 같이 memberSearch()메소드를 추가합니다.
public MemberVO memberSearch(String id) {
MemberVO member = dao.memberSearch(id);
return member;
}
dao패키지의 MemberDAO에 아래와 같이 MemberSearch()메소드를 추가합니다.
public MemberVO memberSearch(String id) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
MemberVO member = null;
try {
conn = connect();
pstmt = conn.prepareStatement("select * from member where id=?");
pstmt.setString(1, id);
rs = pstmt.executeQuery();
if(rs.next()) {
member = new MemberVO();
member.setId(rs.getString(1));
member.setPasswd(rs.getString(2)); //실제 프로젝트에서 패스워드는 검색할 필요가 없습니다.
member.setName(rs.getString(3));
member.setMail(rs.getString(4));
}
}catch(Exception e) {
e.printStackTrace();
}finally {
close(conn,pstmt,rs);
}
return member;
}
결과 값을 출력하기 위해 WebContent/result 경로에 memberSearchOutput.jsp 파일을 작성합니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Read</title>
</head>
<body>
<h3>검색 결과</h3>
<%
String result = (String)request.getAttribute("result");
if(result != null){
out.print(result+"<p>");
}else{
%>
<hr>
<h3>
${member.id} / ${member.passwd} / ${member.name} / ${member.mail}
</h3>
<%
}
%>
<%@ include file="home.jsp" %>
</body>
</html>
회원정보 수정(UPDATE)
먼저 FrontController.java의 init메소드의 주석을 풀어줍니다.
list.put("/memberUpdate.do", new MemberUpdateController());
WebContents 폴더에 memberUpdate.jsp를 작성합니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="vo.MemberVO" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Update</title>
</head>
<body>
<h3>회원 정보 검색</h3>
${error}
<form action="memberSearch.do" method="post">
ID:<input type="text" name="id" />
<input type="hidden" name="job" value="update" />
<input type="submit" value="검색" />
</form>
<%
MemberVO member = (MemberVO)request.getAttribute("member");
if(member != null){
%>
<h3>회원 정보 수정</h3>
<form action="memberUpdate.do" method="post">
ID:<input type="text" name="id" readonly value="${member.id}"><br>
PW:<input type="password" name="passwd" value="${member.passwd }"><br>
이름:<input type="text" name="name" value="${member.name }"><br>
Mail:<input type="text"name="mail" value="${member.mail }"><br>
<input type="submit" value="수정">
</form>
<%
}else{
%>
${result }<p>
<%
}
%>
</body>
</html>
위 form태그에서 요청 URL로 지정한 /memberUpdate.do 요청을 처리하기 위한 컨트롤러를 controller 패키지에 MemberUpdateController.java 으로 생성하여 작성합니다.
package controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import service.MemberService;
import vo.MemberVO;
public class MemberUpdateController implements Controller{
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//request 객체에서 파라미터 추출
String id = request.getParameter("id");
String passwd = request.getParameter("passwd");
String name = request.getParameter("name");
String mail = request.getParameter("mail");
//유효성 체크
if(id.isEmpty() || passwd.isEmpty() || name.isEmpty() || mail.isEmpty()) {
request.setAttribute("error", "모든 항목을 빠짐없이 입력하세요");
HttpUtil.forward(request, response, "/memberUpdate.jsp");
return;
}
//vo 객체에 데이터 바인딩
MemberVO member = new MemberVO();
member.setId(id);
member.setPasswd(passwd);
member.setName(name);
member.setMail(mail);
//서비스 객체의 메서드 호출
MemberService service = MemberService.getInstance();
service.memberUpdate(member);
//결과 페이지로 이동
request.setAttribute("id", id);
HttpUtil.forward(request, response, "/result/memberUpdateOutput.jsp");
}
}
서비스를 처리할 MemberService.java에 memberUpdate()메소드를 추가합니다.
public void memberUpdate(MemberVO member) {
dao.memberUpdate(member);
}
MemberDAO.java 에 memberUpdate()를 추가합니다.
public void memberUpdate(MemberVO member) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = connect();
pstmt = conn.prepareStatement("update member set passwd=?, name=?, mail=? where id=?");
pstmt.setString(1, member.getPasswd());
pstmt.setString(2, member.getName());
pstmt.setString(3, member.getMail());
pstmt.setString(4, member.getId());
pstmt.executeUpdate();
}catch(Exception e) {
e.printStackTrace();
}finally {
close(conn,pstmt);
}
}
결과 화면을 보여주기 위한 View화면을 WebContents/result 경로에 memberUpdateOutput.jsp 파일을 작성합니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>수정 결과</title>
</head>
<body>
<h3> ${id} 님 정보 수정이 완료되었습니다.</h3>
<%@ include file="home.jsp" %>
</body>
</html>
회원정보 삭제(DELETE)
FrontController.java의 init()메소드의 주석을 해제합니다.
그리고 WebContents 경로에 memberDelete.jsp 파일을 작성합니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="vo.MemberVO" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Delete</title>
</head>
<body>
<h3>삭제 정보 검색</h3>
${error}
<form action="memberSearch.do" method="post">
ID:<input type="text" name="id" />
<input type="hidden" name="job" value="delete" />
<input type="submit" value="검색" />
</form>
<%
MemberVO member = (MemberVO)request.getAttribute("member");
if(member != null){
%>
<h3>검색 정보 결과</h3>
${member.id} / ${member.passwd} / ${member.name} / ${member.mail} <p>
<form action="memberDelete.do" method="post">
<input type="hidden" name="id" value="${member.id}"/>
<input type="submit" value="삭제">
</form>
<%
}else{
%>
${result }<p>
<%
}
%>
</body>
</html>
controller 패키지에는 MemberDeleteController.java 를 작성합니다.
package controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import service.MemberService;
public class MemberDeleteController implements Controller{
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//request 객체에서 파라미터 추출
String id = request.getParameter("id");
//서비스 객체의 메서드 호출
MemberService service = MemberService.getInstance();
service.memberDelete(id);
//결과 페이지로 이동
HttpUtil.forward(request, response, "/result/memberDeleteOutput.jsp");
}
}
service 패키지의 서비스 객체 MemberService.java에 memberDelete() 메소드를 추가해줍니다.
public void memberDelete(String id) {
dao.memberDelete(id);
}
이어 dao패키지의 MemberDAO.java 에 memberDelete()메소드를 추가합니다.
public void memberDelete(String id) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = connect();
pstmt = conn.prepareStatement("delete from member where id=?");
pstmt.setString(1, id);
pstmt.executeUpdate();
}catch(Exception e) {
e.printStackTrace();
}finally {
close(conn,pstmt);
}
}
이후 결과 view 페이지 memberDeleteOutput.jsp를 WebContents/result 경로에 생성해줍니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>삭제 결과</title>
</head>
<body>
<h3> 회원 정보가 삭제되었습니다.</h3>
<%@ include file="home.jsp" %>
</body>
</html>
'DEV&OPS > Java' 카테고리의 다른 글
JAVA 보안 Resource Injection (0) | 2022.08.03 |
---|---|
JAVA 보안 SQL Injection (0) | 2022.08.03 |
MVC 패턴 (0) | 2022.07.21 |
JSTL SQL (0) | 2022.07.20 |
JSTL Formatting (0) | 2022.07.20 |