[JSP] DAO & DTO

Junseo Kim·2020년 1월 14일
1

[JSP]JSP기초

목록 보기
15/19

데이터 베이스와 통신하기 위한 기능을 모듈화 하는 것

DAO란?

Data Access Object의 약자로, 서버가 데이터베이스에 접근하는 기능을 모듈화 한 것이다.

DTO란?

Data Transfer Object의 약자로, 데이터베이스의 자료형과 자바의 자료형이 다르기 때문에, 데이터의 가공이 필요한데, 이 때 데이터베이스의 데이터를 자바에서 쓸 수 있게 만들어주는 것이다.

실습해보기

책에 대한 정보를 검색하는 BookServlet을 하나 만들어준다.

package com.servlet;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

@WebServlet("/BookServlet")
public class BookServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html; charset = UTF-8");
        PrintWriter out = response.getWriter();

        // driver loading을 위한 기본 정보
        String database = "jspDB"; // db이름

        String driver = "com.mysql.jdbc.Driver";
        String url = "jdbc:mysql://localhost/" + database;
        String id = "js";
        String pw = "1234";

        // 연결을 위한 Connection 객체
        Connection con = null;

        // 통신하기 위한 statement 객체
        Statement stmt = null;

        // select 결과 값을 담기 위한 ResultSet 객체 
        ResultSet res = null;

        try{
            Class.forName(driver); // driver loading 
            con = (Connection)DriverManager.getConnection(url, id, pw); // connection 
            stmt = (Statement)con.createStatement(); // statement 
            String sql = " SELECT * FROM book "; // query 
            res = stmt.executeQuery(sql); // run 

            // select 쿼리의 결과 값을 한 행씩 읽어온다. 
            while(res.next()){
                int bookId = res.getInt("book_id");
                String bookName = res.getString("book_name");
                String bookLoc = res.getString("book_loc");

                out.print("book id: "+ bookId+ ", ");
                out.print("book name: "+ bookName+ ", ");
                out.print("book location: "+ bookLoc+ "<br>  ");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally { // 자원을 반납해준다. 
            try {
                if(res != null) res.close();
                if(stmt != null) stmt.close();
                if(con != null) con.close();
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }
}

위의 코드는 DAO와 DTO를 사용하지 않은 코드이다. 이 코드를 DAO와 DTO를 사용하여 변화시켜보겠다.

그럼 BookServlet.java / BookDAO.java / BookDTO.java 총 3개의 파일로 나눠지는 것이다.

BookDTO

먼저 BookDTO부터 만들어 보겠다.(일반적으로 .dto 패키지를 새로 만들어서 dto파일들 끼리 모아놓는다.)

DTO는 데이터베이스의 자료형을 자바에서 쓸 수 있게 바꿔주는 역할을 하기 때문에, 해당 테이블의 정보를 가지고 있다. 따라서 해당 테이블의 column 들을 변수로 선언해주고, 초기화 해주고, getter를 이용하여 값을 가져올 수 도 있어야한다.

스크린샷 2020-01-15 오전 5.10.25.png

BookDAO

실질적으로 DB와 연결하고, 데이터를 가져오는 것은 DAO에서 일어난다.

DAO도 DTO와 마찬가지로 일반적으로 .dao 패키지를 새로 만들어 DAO 파일끼리 모아서 사용한다.

먼저, DAO의 생성자에서 driver loading을 해준다. 즉 DAO 객체가 호출됨과 동시에 DB 드라이버도 메모리에 올려주는 것이다.

스크린샷 2020-01-15 오전 5.14.20.png

그런 다음 필요한 기능들을 메서드로 만들어서 구현한다. select 메서드를 예시로 만들어보겠다.(필요에 따라 update, delete, insert 등 여러 메서드를 구현해서 사용하면 된다.)

select 쿼리는 리턴 값이 많기 때문에 ArrayList로 받아줘야한다. ArrayList의 타입은 아까 만들어 준, BookDTO 타입이다. 즉, DTO를 이용해서 DB의 데이터를 자바에서 다룰 수 있는 것이다.

먼저, ArrayList를 선언해주고, Connection 객체 / PreparedStatement(or Statement) 객체 / ResultSet 객체(select 쿼리이기 때문) 를 선언해준다.

스크린샷 2020-01-15 오전 5.18.58.png

실제로 DB에 접근하는 부분은 DAO와 DTO를 쓰지 않을 때 처럼, try - catch구문을 사용해주어야한다.

driver loading 단계는 DAO객체가 생성 될 때, 생성자에서 해주었기 때문에, connection 단계부터 진행한다.

스크린샷 2020-01-15 오전 5.20.16.png

DB에서 데이터를 읽어와서 DTO 객체를 호출한 후, 생성된 DTO 객체를 ArrayList에 넣어준다.

스크린샷 2020-01-15 오전 5.23.15.png

마지막으로, 사용한 객체들의 resource를 반납해준다.

스크린샷 2020-01-15 오전 5.23.56.png

select 메서드는 아래와 같다.
스크린샷 2020-01-15 오전 5.28.28.png

BookServlet

DAO와 DTO를 이용하여, DB에 관한 기능들을 분리시켰기 때문에, 기존 servlet에서는 DAO객체만 생성해주고, 만들어준 메서드를 사용만 해주면 된다.

스크린샷 2020-01-15 오전 5.26.32.png

전체코드

// BookServlet.java

package com.servlet;

import com.servlet.dao.BookDAO;
import com.servlet.dto.BookDTO;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

@WebServlet("/BookServlet")
public class BookServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html; charset = UTF-8");
        PrintWriter out = response.getWriter();

        BookDAO bookDAO = new BookDAO(); // DAO 객체 호출(DB driver 메모리에 올라감)
        ArrayList<BookDTO> list = bookDAO.select(); // DAO 객체의 select 메서드 호출

        // 출력해보기
        for(int i=0;i<list.size();i++){
            BookDTO bookDTO = list.get(i);

            int bookId = bookDTO.getBookId();
            String bookName = bookDTO.getBookName();
            String bookLoc = bookDTO.getBookLoc();

            out.print("book id: "+ bookId+ ", ");
            out.print("book name: "+ bookName+ ", ");
            out.print("book location: "+ bookLoc+ "<br>  ");
        }
    }
}
// BookDAO.java

package com.servlet.dao;

import com.mysql.jdbc.Connection;
import com.servlet.dto.BookDTO;

import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;

public class BookDAO {

    // driver loading을 위한 기본 정보
    String database = "jspDB"; // db이름

    String driver = "com.mysql.jdbc.Driver";
    String url = "jdbc:mysql://localhost/" + database;
    String id = "js";
    String pw = "1234";

    // BookDAO가 생성되면서 같이 드라이버도 메모리에 올라갈 수 있도록 생성자에 코딩
    public BookDAO() {
        try{
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 실제로 DB에 접근하여 데이터를 가져오는 역할을 하는 메서드
    public ArrayList<BookDTO> select() {
        ArrayList<BookDTO> list = new ArrayList<BookDTO>();

        // 연결을 위한 Connection 객체
        Connection con = null;
        // 통신하기 위한 PreparedStatement 객체
        PreparedStatement pstmt = null;
        // select 결과 값을 담기 위한 ResultSet 객체
        ResultSet res = null;

        // 실제로 DB에 접근하는 부분
        try{
            con = (Connection) DriverManager.getConnection(url, id, pw); // connection
            String sql = "SELECT * FROM book"; // query
            pstmt = con.prepareStatement(sql); // preparedStatement
            res = pstmt.executeQuery(); // run

            while(res.next()){
                int bookId = res.getInt("book_id");
                String bookName = res.getString("book_name");
                String bookLoc = res.getString("book_loc");

                BookDTO bookDTO = new BookDTO(bookId, bookName, bookLoc); // DTO 객체에 DB에서 읽어온 값 넣어서 호출
                list.add(bookDTO); // arraylist에 생성된 DTO객체 넣어줌
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(res != null) res.close();
                if(pstmt != null) pstmt.close();
                if(con != null) con.close();
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return list;
    }
}
// BookDTO.java

package com.servlet.dto;

// book에 대한 정보를 가지고 있는 것
public class BookDTO {

    // book DB의 column을 모두 만들어 줌
    int bookId;
    String bookName;
    String bookLoc;

    // 생성자에서 변수들 초기화
    public BookDTO(int bookId, String bookName, String bookLoc) {
        this.bookId = bookId;
        this.bookName = bookName;
        this.bookLoc = bookLoc;
    }

    public int getBookId() {
        return bookId;
    }

    public String getBookName() {
        return bookName;
    }

    public String getBookLoc() {
        return bookLoc;
    }
}

0개의 댓글