[JSP] DAO, DTO를 이용한 CRUD (Oracle)

108971 단어 jspjsp

DAO(Data Access Object)

  • DAO는 데이터베이스에 관련된 작업을 담당하는 객체이다.
  • 실질적으로 데이터베이스에 접근한다.
  • 효율적으로 커넥션을 사용, 유지보수 및 보안을 위해 사용한다.
  • DB 접속 후 CRUD(Create Read Update Delete) 작업을 실행해주는 클래스이다.
  • 데이터베이스 접근을 하기 위한 로직과 비즈니스 로직을 분리하기 위해 사용한다.

DTO(Data Transfer Object)

  • 계층간 데이터 교환을 위한 자바빈즈를 뜻한다.
  • 로직을 가지지 않은 순수한 데이터 객체이며 필드와 getter, setter 메소드만 존재한다.
  • 데이터베이스에 있는 데이터를 자바 형태로 만들어주는 중간 매체.

식당 리스트를 만들어보자!

Database/DAO/DTO 설정하기

  1. Oracle을 이용해 Restaurant 이름의 table 생성
  • RESTAURANT 이름(NAME) - null값 허용 x
  • 전화번호(PHONE) - 기본키
  • 위치(LOC)
  • 여는시간(OPENTIME)
  • 닫는시간(CLOSETIME)
CREATE TABLE RESTAURANT(
    NAME VARCHAR(20) NOT NULL,
    PHONE VARCHAR(15) PRIMARY KEY,
    LOC VARCHAR(50),
    OPENTIME VARCHAR(10),
    CLOSETIME VARCHAR(10)
);

  1. src/main/java/model 패키지를 만든 후 ResDTO.java 파일 생성
package model;

public class ResDTO {

	String Name;
	String Phone;
	String Loc;
	String OpenTime;
	String CloseTime;
	
	public String getName() {
		return Name;
	}
	public void setName(String name) {
		Name = name;
	}
	public String getPhone() {
		return Phone;
	}
	public void setPhone(String phone) {
		Phone = phone;
	}
	public String getLoc() {
		return Loc;
	}
	public void setLoc(String loc) {
		Loc = loc;
	}
	public String getOpenTime() {
		return OpenTime;
	}
	public void setOpenTime(String openTime) {
		OpenTime = openTime;
	}
	public String getCloseTime() {
		return CloseTime;
	}
	public void setCloseTime(String closeTime) {
		CloseTime = closeTime;
	}
}
  • 마우스 우 클릭 Source/Generate Getters and Setters 를 클릭하면 쉽게 생성할 수 있다.


  1. Connection pool 설정
  <Context docBase="Restaurant" path="/Restaurant" reloadable="true" source="org.eclipse.jst.jee.server:Restaurant">
      <Resource auth="Container" driverClassName="oracle.jdbc.driver.OracleDriver" loginTimeout="10" maxWait="5000" name="jdbc/pool_2" password="1234" type="javax.sql.DataSource" url="jdbc:oracle:thin:@localhost:1521:XE" username="sys as SYSDBA"/>
      </Context>

  1. src/main/java/model ResDAO.java 생성
  • 실질적으로 데이터베이스에 접근.
  • 여기서는 Connection Pool 사용.
package model;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

public class ResDAO {
	Connection con;
	ResultSet rs; //db의 테이블 결과를 리턴받아 자바에 저장해주는 객체
	PreparedStatement pstmt; //DB에서 쿼리를 실행시켜주는 객체
	public void dbConnetcion() {
		try {
			//외부에서 데이터를 읽어드려야해서 Context 사용
			Context initctx = new InitialContext();
			//톰캣 서버에 정보를 담아놓은 곳으로 이동
			Context envctx = (Context) initctx.lookup("java:comp/env"); //자바 환경설정
			//데이터소스 객체 선언. Resource name 값을 찾아옴.
			DataSource ds = (DataSource) envctx.lookup("jdbc/pool_2");
			//데이터 소스를 기준으로 커넥션을 연결
			con = ds.getConnection();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}//dbConnection() end
}//ResDAO end

테이블 생성

  1. Main.jsp : 식당 리스트가 들어갈 테이블
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Restaurant List</title>
</head>
<body>
<h2>식당 리스트</h2>
<button onclick="location.href='Register.jsp'">등록하기</button>

<table border="1">
	<tr height="50">
		<td align="center" width="150">식당이름</td>
		<td align="center" width="150">전화번호</td>
		<td align="center" width="150">위치</td>
		<td align="center" width="150">여는시간</td>
		<td align="center" width="150">닫는시간</td>
	</tr>
</table>
</body>
</html>
  • 결과

  • 등록하기 버튼을 눌러도 아직 데이터를 보여주는 메소드를 작성하지 않아서 빈 테이블만 보여준다.


식당 등록하기

  1. Register.jsp : 등록하기 버튼을 누르면 식당을 등록
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h2>맛집 등록</h2>
	<form action="RegisterProc.jsp" method="post">
	<table width="500" border="1">
	<tr height="50">
		<td align="center" width="120">식당이름 </td>
		<td align="center" width="200"><input type="text" name="Name" placeholder="식당이름을 입력하세요" size="40"></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">전화번호 </td>
		<td align="center" width="200"><input type="text" name="Phone" placeholder="전화번호를 입력하세요" size="40"></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">위치 </td>
		<td align="center" width="200"><input type="text" name="Loc" placeholder="위치를 입력하세요" size="40"></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">여는시간 </td>
		<td align="center" width="200"><input type="text" name="OpenTime" placeholder="09:00" size="40"></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">닫는시간 </td>
		<td align="center" width="200"><input type="text" name="CloseTime" placeholder="10:00" size="40"></td>
	</tr>
</table>
<input type="submit" value="등록하기">
</form>
</body>
</html>
  • 결과

  • 등록하기 버튼을 누르면 RegisterProc.jsp 로 페이지가 이동한다.(현재는 없는 페이지)


  1. ResDAO.java : 등록하기 버튼을 눌렀을 때 식당 리스트를 생성해줄 InsertData( ) 메소드 작성
public void InsertData(ResDTO mbean){
		try {
        	//db 연결
			dbConnetcion();
            //Insert 쿼리 준비
			String sql = "INSERT INTO RESTAURANT VALUES(?,?,?,?,?)";
            //쿼리를 사용할 수 있도록 설정.
			pstmt = con.prepareStatement(sql);
            // ? 에 맞게 데이터를 맵핑.
			pstmt.setString(1,mbean.getName());
			pstmt.setString(2,mbean.getPhone());
			pstmt.setString(3,mbean.getLoc());
			pstmt.setString(4,mbean.getOpenTime());
			pstmt.setString(5,mbean.getCloseTime());
			//insert, update, delete를 실행하는 메소드
			pstmt.executeUpdate();
            //자원반납
			con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}//InsertData end

3. RegisterProc.jsp : 등록하기 버튼을 눌렀을 때 식당 리스트를 보여줄 InsertData( ) 메서드 실행

  • 식당 추가 후 Main.jsp로 돌아감
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="model.ResDAO" %>
<%@ page import="model.ResDTO" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<%
	request.setCharacterEncoding("UTF-8");
	//Register.jsp에서 넘어온 데이터를 각각 변수에 저장.
	String Name = request.getParameter("Name");
	String Phone = request.getParameter("Phone");
	String Loc = request.getParameter("Loc");
	String OpenTime = request.getParameter("OpenTime");
	String CloseTime = request.getParameter("CloseTime");
  
	//ResDTO 객체에 넘어온 데이터를 각각의 필드에 저장
	ResDTO data = new ResDTO();
	data.setName(Name);
	data.setPhone(Phone);
	data.setLoc(Loc);
	data.setOpenTime(OpenTime);
	data.setCloseTime(CloseTime);

	//ResDAO에 있는 InsertData() 호출 후 ResDTO 객체를 전달.
	ResDAO rdao = new ResDAO();
	rdao.InsertData(data);
 
	//실행 후 Main.jsp로 돌아감
	response.sendRedirect("Main.jsp");
%>
</body>
</html>
  • 결과
  • 아직 Main.jsp 테이블에 리스트는 없지만 데이터베이스에 데이터가 입력이 잘 되어있다.


식당 리스트 보여주기

  1. ResDAO.java : 식당을 추가한 리스트를 보여줄 allRestaurant( ) 메소드 작성
public ArrayList<ResDTO> allRestaurant() {
  		//Arraylist 클래스를 이용해 가변 길이의 데이터를 저장.
		ArrayList<ResDTO> list = new ArrayList<>();
		dbConnetcion();
		String sql = "SELECT * FROM RESTAURANT";
		try {
			pstmt = con.prepareStatement(sql);
			rs = pstmt.executeQuery();
 
			while(rs.next()) {  //컬럼으로 나뉘어진 데이터를 빈 클래스에 저장.
				ResDTO rdto = new ResDTO();
 
				rdto.setName(rs.getString(1));
				rdto.setPhone(rs.getString(2));
				rdto.setLoc(rs.getString(3));
				rdto.setOpenTime(rs.getString(4));
				rdto.setCloseTime(rs.getString(5));
				list.add(rdto);
			}
			con.close();
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return list;
	}//allRestaurant() end

  1. Main.jsp : allRestaurant() 메소드 호출
<%@page import="model.ResDAO"%>
<%@page import="java.util.ArrayList"%>
<%@page import="model.ResDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Restaurant List</title>
</head>
<body>
<%
	request.setCharacterEncoding("UTF-8");
	ResDAO rdao = new ResDAO();
	ArrayList<ResDTO> list = rdao.allRestaurant();
%>
<h2>식당 리스트</h2>
<button onclick="location.href='Register.jsp'">등록하기</button>
<table border="1">
	<tr height="50">
		<td align="center" width="200">이름</td>
		<td align="center" width="100">전화번호</td>
		<td align="center" width="250">위치</td>
		<td align="center" width="100">여는시간</td>
		<td align="center" width="100">닫는시간</td>
	</tr>
	<%
	for(int i=0;i<list.size();i++){
		ResDTO rdto = list.get(i);
	%>
	
	<tr height="50">
		<td align="center" width="200"><%=rdto.getName() %></td>	
		<td align="center" width="100"><%=rdto.getPhone() %></td>
		<td align="center" width="250"><%=rdto.getLoc() %></td>
		<td align="center" width="100"><%=rdto.getOpenTime() %></td>
		<td align="center" width="100"><%=rdto.getCloseTime() %></td>

	</tr>
	<%
	}
	%>	
</table>
</body>
</html>
  • 결과

  • 이전에 입력한 데이터가 잘 들어간 것이 확인된다.

식당 이름 클릭시 개별 정보 페이지로 이동

  1. Main.jsp : 식당이름에 링크를 건다.
<tr height="50">
		<td align="center" width="200">
		<a href="listInfo.jsp?Name=<%=rdto.getName() %>">
		<%=rdto.getName() %>
		</a></td>
		
		<td align="center" width="100"><%=rdto.getPhone() %></td>
		<td align="center" width="250"><%=rdto.getLoc() %></td>
		<td align="center" width="100"><%=rdto.getOpenTime() %></td>
		<td align="center" width="100"><%=rdto.getCloseTime() %></td>
</tr>
  • 결과

  1. listInfo.jsp : 식당 이름을 클릭했을 때, 클릭한 식당의 정보를 보여주는 페이지
<%@page import="model.ResDAO"%>
<%@page import="model.ResDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
	<table border="1">
	<tr height="50">
		<td align="center" width="120">식당이름 </td>
		<td align="center" width="200"></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">전화번호 </td>
		<td align="center" width="200"></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">위치 </td>
		<td align="center" width="200"></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">여는시간 </td>
		<td align="center" width="200"></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">닫는시간 </td>
		<td align="center" width="200"></td>
	</tr>
</table>
</body>
</html>
</html>
  • 결과

  1. ResDAO.java : 이름을 클릭한 식당 정보를 보여줄 selectName( ) 메소드 작성
public ResDTO selectName(String Name) {
		//한사람에 대한 정보만 리턴하기에 빈 클래스 객체 생성.
		ResDTO rdto = new ResDTO();
		//선택한 이름값과 db에 있는 이름값이 같은 데이터를 갖고옴.
		String sql = "SELECT * FROM RESTAURANT WHERE NAME=?";
		try {
			dbConnetcion();
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, Name);
			rs=pstmt.executeQuery();
			if(rs.next()) {
				rdto.setName(rs.getString(1));
				rdto.setPhone(rs.getString(2));
				rdto.setLoc(rs.getString(3));
				rdto.setOpenTime(rs.getString(4));
				rdto.setCloseTime(rs.getString(5));
			}
			con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return rdto;
	}

  1. listInfo.jsp : 클릭한 식당의 정보를 보여줄 selectName() 메소드 호출
<%@page import="model.ResDAO"%>
<%@page import="model.ResDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<%
	request.setCharacterEncoding("UTF-8");

	String Name = request.getParameter("Name");
	ResDAO rdao = new ResDAO();
	ResDTO rdto = rdao.selectName(Name);
%>
	<table border="1">
	<tr height="50">
		<td align="center" width="120">식당이름 </td>
		<td align="center" width="200"><%=rdto.getName()%></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">전화번호 </td>
		<td align="center" width="200"><%=rdto.getPhone()%></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">위치 </td>
		<td align="center" width="200"><%=rdto.getLoc()%></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">여는시간 </td>
		<td align="center" width="200"><%=rdto.getOpenTime()%></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">닫는시간 </td>
		<td align="center" width="200"><%=rdto.getCloseTime()%></td>
	</tr>
</table>
</body>
</html>
  • 결과


수정하기

  1. listInfo.jsp : 수정하기 버튼 추가
<tr height="50">
	<td align="center" colspan="2">
	<button onclick="location.href='listUpdate.jsp?Name=				  <%=rdto.getName()%>'">수정하기</button>
</td>
</tr>
  • 결과


2. listUpdate.jsp : 수정하기 버튼 클릭 시 수정할 수 있는 페이지

<%@page import="model.ResDAO"%>
<%@page import="model.ResDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<%
	request.setCharacterEncoding("UTF-8");

	String Name = request.getParameter("Name");
	ResDAO rdao = new ResDAO();
	//이전에 만들어놓은 메소드를 이용해 데이터를 폼에 뿌려줌
	ResDTO rdto = rdao.selectName(Name);
%>
<form action="listUpdateProc.jsp" method="post">
	<table border="1">
	<tr height="50">
		<td align="center" width="120">식당이름 </td>
		<td align="center" width="200">
		<input type="hidden" name="Name" value="<%=rdto.getName() %>">
		<%=rdto.getName()%></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">전화번호 </td>
		<td align="center" width="200"><input type="text" name="Phone" size="40"
		value="<%=rdto.getPhone()%>"></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">위치 </td>
		<td align="center" width="200"><input type="text" name="Loc" size="40"
		value="<%=rdto.getLoc()%>"></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">여는시간 </td>
		<td align="center" width="200"><input type="text" name="OpenTime"size="40"
		value="<%=rdto.getOpenTime()%>"></td>
	</tr>
	<tr height="50">
		<td align="center" width="120">닫는시간 </td>
		<td align="center" width="200"><input type="text" name="CloseTime" size="40"
		value="<%=rdto.getCloseTime()%>"></td>
	</tr>
</table>
<input type="submit" value="확인">
<input type="button" value="취소" onclick="location.href='Main.jsp'">
</form>
</body>
</html>
  • 결과

  • 식당이름은 변경할 수 없게 해놓았다.

  1. ResDAO.java : 식당 정보를 수정할 수 있는 updateInfo( ) 메소드 작성
public void updateInfo(ResDTO mbean) {
		dbConnetcion();
		try {
			String sql = "UPDATE RESTAURANT SET PHONE=?, LOC=?,OPENTIME=?,"
					+ "CLOSETIME=? WHERE NAME=?";
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, mbean.getPhone());
			pstmt.setString(2, mbean.getLoc());
			pstmt.setString(3, mbean.getOpenTime());
			pstmt.setString(4, mbean.getCloseTime());
			pstmt.setString(5, mbean.getName());
			pstmt.executeUpdate();
			
			con.close();
			
		}catch(Exception e) {
			e.printStackTrace();
		}
	}//updateInfo end

  1. listUpdateProc.jsp : 수정하기 버튼 클릭시 식당 정보를 수정할 수 있는 updateInfo( ) 메소드 호출
<%@page import="model.ResDAO"%>
<%@page import="model.ResDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<%
	request.setCharacterEncoding("UTF-8");

	String Name = request.getParameter("Name");
	String Phone = request.getParameter("Phone");
	String Loc = request.getParameter("Loc");
	String OpenTime = request.getParameter("OpenTime");
	String CloseTime = request.getParameter("CloseTime");
	
	ResDTO data = new ResDTO();
	data.setName(Name);
	data.setPhone(Phone);
	data.setLoc(Loc);
	data.setOpenTime(OpenTime);
	data.setCloseTime(CloseTime);
	
	ResDAO rdao = new ResDAO();
	rdao.updateInfo(data); //data 자체에 수정할 내용이 그대로있어서
	response.sendRedirect("Main.jsp");
%>
</body>
</html>
  • 결과

  • Main.jsp


삭제하기

  1. listInfo.jsp : 삭제하기 버튼 추가
<button onclick="location.href='listDeleteProc.jsp?Name=<%=rdto.getName()%>'">삭제하기</button>
  • 결과

  1. ResDAO.java : 식당을 삭제할 수 있는 deleteInfo() 메소드 작성
public void deleteInfo(String name) {
		dbConnetcion();
		try {
			String sql = "DELETE FROM RESTAURANT WHERE NAME=?";
			pstmt =con.prepareStatement(sql);
			pstmt.setString(1, name);
			pstmt.executeUpdate();
			System.out.println(name);
			con.close();
		}catch (Exception e) {
			e.printStackTrace();
		}
	} //deleteInfo end코드를 입력하세요

  1. listDeleteProc.jsp : 삭제하기 버튼 클릭시 식당을 삭제할 수 있는 deleteInfo() 호출
<%@page import="model.ResDAO"%>
<%@page import="model.ResDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<%
	request.setCharacterEncoding("UTF-8");
	String Name = request.getParameter("Name");
	System.out.println("request="+Name);
	ResDTO data = new ResDTO();
	data.setName(Name);
	
	ResDAO rdao = new ResDAO();
	rdao.deleteInfo(Name);
	
	response.sendRedirect("Main.jsp");
%>
</body>
</html>
  • 삭제하기 버튼 클릭시 삭제가 잘 되어있다.

  • 깃 주소

    Restaurant source


  • 이로서 간단한 CRUD가 끝이 났다.
    혹시라도 잘못된 부분이 있으면 댓글 부탁드립니다.

좋은 웹페이지 즐겨찾기