JSP

[JSP] DAO, DTO

shb 2022. 4. 6. 16:25

기존 프로그래밍 방식의  문제점

1. 프로그래밍 부분 (비지니스 로직, 백엔드) 부분과 웹 구조(html css js 등의 프론트 엔트, 프레젠테이션로직) 부분 이 하나의 파일 안에 뒤얽혀 있음.

2. insert. delete, list, find 파일을 보면 ’DB커넥션’을 만드는 과정들이 매 페이지 요청 마다 계속 동일하게 반복된다.  매번 커넥션을 발생시키고 해제하는 동일한 코드가 반복 되는 것이 생산성에도 문제가 된다.

3. 조금만 규모가 커지면, 분업 제작하기도 힘들고, 유지관리도 어렵다.
‘프로그래밍’과 ‘웹 구조’를 분리해야할 필요성 대두! 이를 위해 자바빈을 활용한 DAO,DTO 개발기술 소개.

 

Presentation Logic /  Business Logic


* DAO, DTO
빈(Bean)을 활용한 대표적인 사례 :  DAO, DTO !
DAO(Data Access Object)DB 데이터 소스 접근을 목적으로 (전담)하는 객체
DTO(Data Transfer Object)데이터가 포함된 객체다른 시스템으로 전달하는 역할을 하는 객체                         

DB에 있는 레코드를 객체화한 클래스 혹은 VO(Volume Object) 라고 말한다 
 (그러나 VO는 read only /immutable속성 가짐)

 

* DB, SQL 관련 상수 정의 클래스
DB접속 정보, 쿼리문, 테이블명, 컬럼명 등은 별도로 관리하든지, XML 등에서 통합 관리하는 것이 좋다.  (직전의 예제에서는 jsp 파일들에 여기저기 흩어져 있고 중복되어 타이핑 되어 있다) 

이번 예제에서는 별도의 클래스에서 관리합니다
상수만 있는 경우 굳이 class 가 아닌 interface 가능
클래스 작성 - 패키지 : common, 클래스 : D.java

 

* DTO 객체 생성
테이블의 필드와 동일한 필드 구성을 갖는 bean 클래스를 만드는 것
- 기본생성자 작성

- 매개변수 생성자 작성
- getter/setter 메소드 작성 
- toString() 오버라이딩 : 있으면 디버깅시 편리.

 

* WriteDTO.java 생성
패키지 : com.lec.beans
클래스 : WriteDTO.java
기본생성자,  getter/setter 작성하기
가능한, 다음 3가지는 이름을 일치시켜주는게 좋음
-> 자바 클래스 필드명  / DB 테이블 필드명 / HTML form 의 name명

 

* DAO 객체 생성 :  DAO 클래스 생성
DAO : Data Access Object  (DB 에 접근하기 위한 객체)
DB 커넥션 등을 통합하고, Connection, PreparedStatement, Statement, ResultSet 객체 관리
- DB 의 url, id, pw  관리
- DTO 객체를 통해 데이터 연결
패키지 : com.lec.beans
클래스 : WriteDAO.java 

 

DAO 객체 생성 :  멤버변수들
DAO 객체, 인스턴스 변수및 기본생성자,  close() 메소드
필요한 import 꼭!

 

- DAO에는 이후 웹어플리케이션에서 필요한 데이터 동작 / 트랜잭션들에 관한 메소드들을 정의해서 사용하면 된다.
- 일체의 데이터는 DAO가 통합관리 하는 셈이 된다.  이를 통해 ‘프로그래밍 영역’과 ‘웹 영역’이 구분될수 있는 기반 
- 다루는 데이터의 종류에 따라 DAO는 여러개 정의하여 사용 가능.
ex) 회원데이터용 DAO,  게시판 데이터용 DAO …


1 작성 동작 : DAO + writeOk.jsp
2 글읽기 동작 : DAO + view.jsp
3 목록보기 동작 : DAO + list.jsp
4 수정 동작 : DAO + update.jsp, updateOk.jsp 
5 삭제 동작 : DAO + deleteOk.jsp
도 DAO+DTO 버젼으로 만들어 봐야 합니다.

 

* writeOk.jsp 

1. ‘작성’ :  파라미터,  유효성 검증 - DAO bean 생성, 폼 검증, 기존 import 삭제

DAO 객체를 사용하여 멤버데이터를 INSERT - 기존의 try-catch 구문도 필요없음

작성 : DTO 사용 버전 - form 에서 넘어온 parameter 를 DTO에 한번에 받아온다!

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<jsp:useBean id="dao" class="com.lec.beans.WriteDAO"/> <%-- DAO bean 생성 --%>
<%
request.setCharacterEncoding("utf-8");  // POST 한글 인코딩 꼭!
	// ※ 이단계에서 parameter 검증 필요
%>
<jsp:useBean id="dto" class="com.lec.beans.WriteDTO"/> <!-- form 데이터 받아오는 DTO -->
<jsp:setProperty property="*" name="dto"/>

<% // dao 사용한 트랜잭션
	int cnt = dao.insert(dto);
%>

<% if(cnt == 0){ %>
	<script>
		alert("등록 실패");
		history.back();
	</script>
<% } else { %>
	<script>
		alert("등록 성공");
		location.href = "view.jsp?uid=<%= dto.getUid() %>";
	</script>
<% } %>

 

* view.jsp

SELECT 쿼리의 결과는 ResultSet 이다. 이를 Java 에서 다루기 편한 List<>로 변환해서 리턴하는 메소드 준비

읽기 : DAO에 readByUid() 추가 - 두개의 쿼리가 트랜잭션으로 처리를 해주어야 한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import = "com.lec.beans.*,java.util.*" %>
<jsp:useBean id="dao" class="com.lec.beans.WriteDAO"/> <%-- DAO bean 객체 생성 --%>

<% // parameter 받아오기
	int uid = Integer.parseInt(request.getParameter("uid"));
	// ※ 이 단계에서 parameter 검증 필요
%>
<% // dao 사용한 트랜잭션
	List<WriteDTO> list = dao.readByUid(uid);
%>
<% if(list.size()  == 0){ %>
		<script>
			alert("해당 정보가 삭제되거나 없습니다");
			history.back();
		</script>
<%
		return;  // 더이상 JSP 프로세싱 하지 않고 종료
	}
	WriteDTO dto = list.get(0);
%>		

<%
	String name = dto.getName();
	String subject = dto.getSubject();
	String content = dto.getContent();
	int viewcnt = dto.getViewCnt();
//	String regdate = dto.getRegDate().toString();
	String regdate = dto.getRegDateTime();
%>


<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"></script>

    <title>조회 - <%= subject %></title>
</head>

<script>
function chkDelete(){
	var answer = confirm("삭제하시겠습니까?");
	if(answer){
		document.forms['frmDelete'].submit();
	}
}

</script>

<body>
    <div class="container mt-3">
        <h2>조회 - <%= subject %></h2>
        <hr>
        <div class="mb-3 mt-3 clearfix">
            <span class="float-start me-2">uid: <%= uid %></span>
            <span class="float-end ms-4">작성일: <%= regdate %></span>
            <span class="float-end">조회수: <%= viewcnt %></span>
        </div>

        <section>
        	<form name="frmDelete" action="deleteOk.jsp" method="POST">
        		<input type="hidden" name="uid" value="<%= uid %>">
        	</form>
            <div class="mb-3">
                <label for="name">작성자:</label>
                <div class="border bg-light rounded p-2" ><%= name %></div>
            </div>    
            <div class="mb-3 mt-3">
                <label for="subject">제목:</label>
                <div class="border bg-light rounded p-2" ><%= subject %></div>
            </div>    
            <div class="mb-3 mt-3">
                <label for="content">내용:</label>
                <div class="border bg-light rounded p-2" ><%= content %></div>
            </div>    

            <a class="btn btn-outline-dark" href="update.jsp?uid=<%= uid %>">수정</a>
            <a class="btn btn-outline-dark" href="list.jsp">목록</a>
            <button type="button" class="btn btn-outline-dark" onclick="chkDelete()">삭제</button>
            <a class="btn btn-outline-dark" href="write.jsp">작성</a>

        </section>
    </div>
</body>

</html>

 

* list.jsp 

기존의 java.sql.*  에서 import 한 것들은 필요없고 DAO, DTO 객체를 사용하기 위한 import 추가

목록 : DAO에 전체 select() 메소드

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import = "com.lec.beans.*,java.util.*" %>
<jsp:useBean id="dao" class="com.lec.beans.WriteDAO"/> <%-- DAO bean 객체 생성 --%>
<% // dao 사용한 트랜잭션
	List<WriteDTO> list = dao.select();
%>

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"></script>

    <title>목록</title>
</head>

<body>

    <div class="container mt-3">
        <h2>목록</h2>
        <hr>
        
        <table class="table table-hover">
            <thead class="table-success">
                <tr>
                    <th>#</th>
                    <th>제목</th>
                    <th>작성자</th>
                    <th>조회수</th>
                    <th>작성일</th>
                </tr>
            </thead>
            <tbody>
<% for(WriteDTO dto : list){ %>
                <tr>
                    <td><%= dto.getUid() %></td>
                    <td><a href="view.jsp?uid=<%= dto.getUid() %>"><%= dto.getSubject() %></a> </td>
                    <td><%= dto.getName() %></td>
                    <td><%= dto.getViewCnt() %></td>
                    <td><%= dto.getRegDateTime() %></td>
                </tr>
<% } %>
            </tbody>
        </table>
        <div class="row">
            <div class="col-12">
                <a class="btn btn-outline-dark" href="write.jsp">작성</a>
            </div>
        </div>
    </div>

</body>

</html>

 

* update.jsp

일단 읽어와야 한다.  view.jsp 와 비슷.

수정 : DAO 에 selectByUid () 추가

- 특정 uid의 글만 SELECT (조회수 증가 없음, readByUid()와는 다르다.)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import = "com.lec.beans.*,java.util.*" %>
<jsp:useBean id="dao" class="com.lec.beans.WriteDAO"/> <%-- DAO bean 객체 생성 --%>

<% // parameter 받아오기
	int uid = Integer.parseInt(request.getParameter("uid"));
	// ※ 이 단계에서 parameter 검증 필요
%>
<% // dao 사용한 트랜잭션
	List<WriteDTO> list = dao.selectByUid(uid);
%>
<% if(list.size()  == 0){ %>
		<script>
			alert("해당 정보가 삭제되거나 없습니다");
			history.back();
		</script>
<%
		return;  // 더이상 JSP 프로세싱 하지 않고 종료
	}
	WriteDTO dto = list.get(0);
%>		

<%
	String name = dto.getName();
	String subject = dto.getSubject();
	String content = dto.getContent();
	int viewcnt = dto.getViewCnt();
//	String regdate = dto.getRegDate().toString();
	String regdate = dto.getRegDateTime();
%>

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"></script>

    <title>수정 - <%= subject %></title>
</head>

<body>
    <div class="container mt-3">
        <h2>수정</h2>
        <hr>
        <div class="mb-3 mt-3 clearfix">
            <span class="float-start me-2">uid: <%= uid %></span>
            <span class="float-end ms-4">작성일: <%= regdate %></span>
            <span class="float-end">조회수: <%= viewcnt %></span>
        </div>

        <form name="frm" action="updateOk.jsp" method="post">
            <input type="hidden" name="uid" value="<%= uid %>"/>
            <div class="mb-3">
                <label for="name">작성자:</label>
                <div class="border bg-light rounded p-2" ><%= name %></div>
            </div>    
            <div class="mb-3 mt-3">
                <label for="subject">제목:</label>
                <input type="text" class="form-control" id="subject" placeholder="제목을 입력하세요" name="subject" value="<%= subject %>" required>
            </div>
            <div class="mb-3 mt-3">
                <label for="content">내용:</label>
                <textarea class="form-control" rows="5" id="content" placeholder="내용을 입력하세요" name="content"><%= content %></textarea>
            </div>


            <button type="submit" class="btn btn-outline-dark">수정완료</button>
            <button type="button" class="btn btn-outline-dark" onclick="history.back()">이전으로</button>
            <a class="btn btn-outline-dark" href="list.jsp">목록</a>

        </form>
    </div>
</body>

</html>

 

* updateOk.jsp

수정완료 : DAO 에 update() 추가

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<jsp:useBean id="dao" class="com.lec.beans.WriteDAO"/> <%-- DAO bean 생성 --%>
<%
request.setCharacterEncoding("utf-8");  // POST 한글 인코딩 꼭!
	// ※ 이단계에서 parameter 검증 필요
%>
<jsp:useBean id="dto" class="com.lec.beans.WriteDTO"/> <!-- form 데이터 받아오는 DTO -->
<jsp:setProperty property="*" name="dto"/>

<% 	//  dao 사용한 트랜잭션
	int cnt = dao.update(dto);
%>

<% if(cnt == 0){ %>
	<script>
		alert("수정 실패");
		history.back();
	</script>
<% } else { %>
	<script>
		alert("수정 성공");
		location.href = "view.jsp?uid=<%= dto.getUid() %>";
	</script>
<% } %>

* deleteOk.jsp

삭제 : DAO에 deleteByUid() 작성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<jsp:useBean id="dao" class="com.lec.beans.WriteDAO"/> <%-- DAO bean 생성 --%>
<% // parameter 받아오기
	int uid = Integer.parseInt(request.getParameter("uid"));
	// ※ 이 단계에서 parameter 검증 필요
%>
<% // dao 사용한 트랜잭션
	int cnt = dao.deleteByUid(uid);
%>

<% if(cnt == 0){ %>
	<script>
		alert("삭제 실패");
		history.back();
	</script>
<% } else { %>
	<script>
		alert("삭제 성공");
		location.href = "list.jsp";
	</script>
<% } %>

db_test.jsp는 삭제해도 됨.

DAO, DTO 를 사용하여 구성한 것이 MVC model1 방식

'JSP' 카테고리의 다른 글

[JSP] EL : Expression Language  (0) 2022.04.06
[JSP] MVC model2  (0) 2022.04.06
[JSP] JBDC  (0) 2022.04.06
[JSP] 자바 빈  (0) 2022.04.05
[JSP] 세션(Session)  (0) 2022.03.31