본문 바로가기
교재 실습/자바 웹 개발 워크북

63. DAO 만들기 (2)

by Jint 2022. 7. 7.

3. 서블릿에서 DAO 사용하기

web05 프로젝트의 spms.servlets 패키지의 MemberListServlet 클래스의 doGet() 메서드를 수정한다.

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		//데이터베이스 관련 코드를 위한 try ~ catch 블록 (JDBC API 사용시 예외가 발생할 수 있기 때문)
		try {
			//JDBC 드라이버를 로딩하고 데이터베이스 연결 시 컨텍스트 초기화 매개변수에서 해당 정보 가져와 처리.
			ServletContext sc = this.getServletContext();
			//ServletContext에 저장된 DB 커넥션 사용
			conn = (Connection)sc.getAttribute("conn");
			
			MemberDao memberDao = new MemberDao();
			memberDao.setConnection(conn); //셋터 메서드 호출
			
			//DAO의 selectList() 메서드 반환값을 request에 담기
			request.setAttribute("members", memberDao.selectList());
			response.setContentType("text/html; charset=UTF-8");
			//JSP로 출력을 위임한다.
			RequestDispatcher rd = request.getRequestDispatcher("/member/MemberList.jsp");
			rd.include(request, response); //인클루딩
		} catch (Exception e) {
			//throw new ServletException(e);
			request.setAttribute("error", e); //예외 객체를 request에 보관
			RequestDispatcher rd = request.getRequestDispatcher("/Error.jsp");
			rd.forward(request, response); //포워딩
		} finally {
			try {if (rs != null) rs.close();} catch(Exception e) {}
			try {if (stmt != null) stmt.close();} catch(Exception e) {}
			//DB 커넥션 객체를 서블릿에서 관리하지 않으므로 삭제
			//try {if (conn != null) conn.close();} catch(Exception e) {}
		}
	}

MemberDao 클래스를 사용하기 전 셋터 메서드를 먼저 호출하여 ServletContext에서 꺼낸 DB 커넥션 객체를 주입한다.

ServletContext sc = this.getServletContext();
Connection conn = (Connection)sc.getAttribute("conn");

MemberDao memberDao = new MemberDao();
memberDao.setConnection(conn);

이제 MemberListServlet 클래스에는 더이상 데이터베이스와 관련된 코드가 존재하지 않는다. 모두 MemberDao 클래스에 이관되었다. MemberListServlet 클래스가 하는 일은 클라이언트의 요청에 대해 어떤 DAO를 사용하고, 어느 JSP로 그 결과를 보내야 하는지 조정(Control)하는 것이다. 이제서야 컴포넌트 별로 역할 구분이 명확해졌다. 서블릿은 컨트롤러, DAO는 모델, JSP는 뷰의 역할을 수행한다.

 

톰캣 서버를 다시 시작한 뒤, 회원 목록을 요청하면 실행 결과는 이전과 똑같다(그림 1).

그림 1 (회원 목록 페이지)

내부적인 구조만 달라졌기 때문이다.

 

회원 관리의 나머지 서블릿인 MemberAddServlet 클래스, MemberDeleteServlet 클래스, MemberUpdateServlet 클래스, LogInServlet 클래스에도 DAO를 사용하는 구조로 수정했다.

MemberDao 클래스는 다음과 같다.

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 spms.vo.Member;

public class MemberDao {
	Connection connection;
	
	//Connection 객체 주입(의존성 주입, 역제어)
	public void setConnection(Connection connection) {
		this.connection = connection;
	}
	
	//회원 목록 조회
	public List<Member> selectList() throws Exception {
		Statement stmt = null;
		ResultSet rs = null;
		try {
			stmt = connection.createStatement();
			rs = stmt.executeQuery(
					"SELECT MNO,MNAME,EMAIL,CRE_DATE" + 
					" FROM MEMBERS" +
					" ORDER BY MNO ASC");
			ArrayList<Member> members = new ArrayList<Member>();
			while(rs.next()) {
				members.add(new Member()
					   .setNo(rs.getInt("MNO"))
					   .setName(rs.getString("MNAME"))
					   .setEmail(rs.getString("EMAIL"))
					   .setCreatedDate(rs.getDate("CRE_DATE"))	);
			}
			return members;
		} catch (Exception e) {
			throw e;
		} finally {
			try {if (rs != null) rs.close();} catch(Exception e) {}
			try {if (stmt != null) stmt.close();} catch(Exception e) {}
		}
	}
	
	//회원 등록
	public int insert(Member member) throws Exception  {
		PreparedStatement stmt = null;

		try {
			stmt = connection.prepareStatement(
					"INSERT INTO MEMBERS(EMAIL,PWD,MNAME,CRE_DATE,MOD_DATE)"
					+ " VALUES (?,?,?,NOW(),NOW())");
			stmt.setString(1, member.getEmail());
			stmt.setString(2, member.getPassword());
			stmt.setString(3, member.getName());
			return stmt.executeUpdate();
		} catch (Exception e) {
			throw e;
		} finally {
			try {if (stmt != null) stmt.close();} catch(Exception e) {}
		}
	}
	
	//회원 삭제
	public int delete(int no) throws Exception {  
		Statement stmt = null;
		try {
			stmt = connection.createStatement();
			return stmt.executeUpdate(
					"DELETE FROM MEMBERS WHERE MNO=" + no);
		} catch (Exception e) {
			throw e;
		} finally {
			try {if (stmt != null) stmt.close();} catch(Exception e) {}
		}
	}
	
	//회원 상세 정보 조회
	public Member selectOne(int no) throws Exception { 
		Statement stmt = null;
		ResultSet rs = null;
		try {
			stmt = connection.createStatement();
			rs = stmt.executeQuery(
					"SELECT MNO,EMAIL,MNAME,CRE_DATE FROM MEMBERS" + 
					" WHERE MNO=" + no);    
			if(rs.next()) {
				return new Member().setNo(rs.getInt("MNO"))
								   .setEmail(rs.getString("EMAIL"))
								   .setName(rs.getString("MNAME"))
								   .setCreatedDate(rs.getDate("CRE_DATE"));
			} 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) {}
		}
	}
	
	//회원 정보 수정
	public int update(Member member) throws Exception { 
		PreparedStatement stmt = null;
		try {
			stmt = connection.prepareStatement(
					"UPDATE MEMBERS SET EMAIL=?,MNAME=?,MOD_DATE=now()"
					+ " WHERE MNO=?");
			stmt.setString(1, member.getEmail());
			stmt.setString(2, member.getName());
			stmt.setInt(3, member.getNo());
			return stmt.executeUpdate();
		} catch (Exception e) {
			throw e;
		} finally {
			try {if (stmt != null) stmt.close();} catch(Exception e) {}
		}
	}
	
	//있으면 Member 객체 리턴, 없으면 null 리턴
	public Member exist(String email, String password) throws Exception {
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			stmt = connection.prepareStatement(
					"SELECT MNAME,EMAIL FROM MEMBERS"
					+ " WHERE EMAIL=? AND PWD=?");
			stmt.setString(1, email);
			stmt.setString(2, password);
			rs = stmt.executeQuery();
			if (rs.next()) {
				return new Member().setName(rs.getString("MNAME"))
						.setEmail(rs.getString("EMAIL"));
			} else {
				return null;
			}
		} catch (Exception e) {
			throw e;
		} finally {
			try {if (rs != null) rs.close();} catch (Exception e) {}
			try {if (stmt != null) stmt.close();} catch (Exception e) {}
		}
	}
}

 

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

 

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

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

freelec.co.kr

댓글