본문 바로가기
교육, 학습/멀티캠퍼스_풀 스택

JDBC - DAO, DTO 구현

by 개발하는 경제학도 2022. 1. 24.

강의 소개

현재 수강하고 있는 멀티캠퍼스 k-digital 지능형 웹서비스 풀 스택 과정을 수강하며 적은 내용입니다.


 

DAO, DTO

앞선 JDBC구현에서 자바만으로는 이해할 수 없는 SQL문을 DB에 전달하고, 결과를 다시 자바 프로그램에 가져왔었다.

그러나 실행부분, DB에 접근하는 DAO, 데이터 전달용 DTO를 구분하여 각각의 역할을 명료하게 만들어 줄 수 있다.

 

DAO(Data Access Object)

데이터가 있는 저장소에 접근하는 유일한 객체이다.

XXDTO으로 클래스명을 붙여 구분하기 쉽게 한다.

파일 입출력 코드 클래스를 데이터 저장 형태의 파일로 보관한다.

직접 DB에 접근하여 데이터를 삽입, 삭제, 조회 등 조작할 수 있는 기능을 수행하며, 데이터를 실제 DB에 저장한다.

MVC 패턴의 Model에서 이 같은 작업을 수행한다.

 

 

DTO(Data Transfer Object) 

데이터 전달용 클래스이다.

관례적으로 XXDTO으로 클래스명을 붙여 구분을 용이하게 한다.

(DO 혹은 VO로도 혼용되기도 한다.)

DAO와 DB 간의 데이터를 주고받는 클래스이다.  DTO는 로직을 가지지 않는 순수한 데이터 객체(getter & setter만 가진 클래스)이다.

DTO는 계층 간 데이터 교환을 하기 위해 사용하는 객체로,

유저가 입력한 데이터를 DB에 넣는 과정은 아래와 같다.

1) 유저가 자신의 브라우저에서 데이터를 입력하여 form에 있는 데이터를 DTO에 넣어서 전송한다.

2) 해당 DTO를 받은 서버가 DAO를 이용하여 DB로 데이터를 저장한다.

 

VO

DTO와 혼용되어 사용되기도 한다.

VO(Value Object) 값 오브젝트로써 값을 위해 사용된다. read-Only 특징이 있어 사용하는 도중에 변경 불가능하며 오직 읽기만 가능하다.

DTO와 유사하지만 DTO는 setter를 가지고 있어 값이 변할 수 있다.

 

 

관계를 간단히 도식화를 하면 아래와 같다.

 

DTO, DAO 코드 구현

아래와 같은 순서로 호출되고, DB에 접근하는 과정을 구현할 것이다. 또한, insert문과 select문의 사용 예시이다.

메인에서 DAO 호출 -> DAO에서 DB접근해서 데이터 가져옴 -> DTO에서 데이터 받아서 저장하기 위한 테이블만들기 
-> DAO에서 전달받은 DTO를 사용해 DB로 저장(insert)

 

이를 위해서는 먼저 book테이블이 MySQL에 생성되어 있어야 한다. 이전 글의 book테이블을 생성하는 SQL문과 같다.

[조회할 테이블 만드는 SQL]

// 테이블 생성. 어떤 DB에 생성할 것인지는 사용자 지정.
create table book(
    bookNo char(10) primary key,
    bookTitle varchar(30),
    bookAuthor varchar(20),
    bookYear int,
    bookPrice int,
    bookPublisher char(10)
);
​
// 조회할 값 넣기
insert into book values ('B001', '자바프로그래밍', '홍길동', 2021, 30000, '서울출판사');
insert into book values ('B002', '데이터베이스', '이몽룡', 2020, 25000, '멀티출판사');
insert into book values ('B003', 'HTML/CSS', '성춘향', 2021, 18000, '강남출판사'); 
​
// book테이블의 전체 내용 조회
select * from book;

 

여기서 구현하는 코드는 book테이블에 사용자가 키보드로 아래와 같이 입력하면 DB에 insert 된다.

B004 자바스크립트 강길동 2020 28000 서울출판사

 

코드를 다 구현하고 메인 클래스를 실행하면 원하는 출력 결과는 아래와 같다.

B001	자바프로그래밍	홍길동	2021	30000	서울출판사
B002	데이터베이스	이몽룡	2020	25000	멀티출판사
B003	HTML/CSS	성춘향	2021	18000	강남출판사
B004	자바스크립트	강길동	2020	28000	서울출판사

 

 

[메인 코드]

사용자에게 입력을 받고 매서드를 호출하는 클래스이다.

아래와 같은 순서로 구현되어 있다. 

1) 사용자 입력을 받는다.

2) DTO객체를 생성& 입력받은 값으로 초기화한다.

3) DAO객체를 생성한다.

4) DAO의 insert메서드 호출해서 DTO객체를 전달한다.

5) DAO의 select메서드 호출해서 결과를 확인한다.

import java.util.Scanner;

public class BookTest {

	public static void main(String[] args) {
		// 사용자에게 입력받기 
		Scanner stdIn = new Scanner(System.in);
		System.out.println("bookNo : " + "bookTitle : " 
				+ "bookAuthor : " + "bookYear : " 
				+ "bookPrice : " + "bookPublisher : ");
		
		String bookNo = stdIn.next();
		String bookTitle = stdIn.next();
		String bookAuthor = stdIn.next();
		int bookYear = stdIn.nextInt();
		int bookPrice = stdIn.nextInt();
		String bookPublisher = stdIn.next();
		
		
		stdIn.close();
		
		// DTO객체 생성, 입력받은 값으로 초기화
		BookDTO dto = new BookDTO(bookNo, bookTitle, bookAuthor
				, bookYear, bookPrice, bookPublisher);
		
		// DAO객체 생성
		BookDAO dao = new BookDAO();
		// insert문 
		// DAO객체로 위에서 초기화한 DTO객체전달 
		dao.insertBook(dto);   
		// select문 
		dao.selectBook();
	}

}

 

[DAO 코드]

데이터가 있는 저장소(즉, DB)에 접근하는 클래스이다.

아래와 같은 순서로 구현되어 있다.

1) JDBC 드라이버를 로드한다.

2) DB에 연결한다.

3) SQL문을 작성하고 DB에 전달한다.

4) DTO에서 변수들을 전달받아 SQL문을 완성한다.

5) SQL문을 실행한다.

6) DB 연결을 해제한다.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class BookDAO {

	Connection conn = null;
	PreparedStatement pt = null;

	// insert문 구현 
	// book 테이블에 데이터 저장
	public void insertBook(BookDTO bookDTO) {
		try {
			// JDBC 드라이버 로드.
			Class.forName("com.mysql.cj.jdbc.Driver");
			// DB 연결.
			conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/접속할 DB", "MySQL아이디", "MySQL비밀번호");
			
			// SQL문
            // (Statement와 달리)PrepareStatement에서는 넣을 값들을 ?로 표시하며, ?가 쓰인 순서로 변수를 구분한다.
			String insertSQL = "insert into book values(?, ?, ?, ?, ?, ?)";
			// conn에 SQL문 전송. 즉 DB로 전달.
			pt = conn.prepareStatement(insertSQL);
			
			// SQL 입력파라미터값 설정. setXX메서드(SQL문에서 ?순서, ?값을 할당할 DTO객체의 변수명)
			pt.setString(1, bookDTO.getBookNo());
			pt.setString(2, bookDTO.getBookTitle());
			pt.setString(3, bookDTO.getBookAuthor());
			pt.setInt(4, bookDTO.getBookYear());
			pt.setInt(5, bookDTO.getBookPrice());
			pt.setString(6, bookDTO.getBookPublisher());
			
			// executeUpdate 메서드: insert문 실행 
			pt.executeUpdate();
			
			// DB 연결 해제 
			pt.close();
			conn.close();

			// 예외처리 
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// select문 구현
	// book 테이블에 있는 모든 데이터 출력
	public void selectBook() {
		List<BookDTO> books = new ArrayList<BookDTO>();
		
		try {
			// JDBC 드라이버 로드.
			Class.forName("com.mysql.cj.jdbc.Driver");
			// DB 연결.
			conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/접속할 DB", "MySQL아이디", "MySQL비밀번호");
			
			String selectSQL = "select * from book";
			
			pt = conn.prepareStatement(selectSQL);
			ResultSet rs = pt.executeQuery();
			
			// DTO에서 값 읽어오기
			while(rs.next()) {
				BookDTO dto = new BookDTO(rs.getString("bookNo"), rs.getString("bookTitle"), 
						rs.getString("bookAuthor"), rs.getInt("bookYear"), 
						rs.getInt("bookPrice"), rs.getString("bookPublisher"));
				
				// 리스트에 한 행씩 담기
				books.add(dto);
			}

			// 한 행씩 출력
			for(BookDTO onebook : books) {
				System.out.println(onebook);
			}
			
			// DB연결 해제
			pt.close();
			conn.close();

		// 예외처리 
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
}

 

[DTO 코드]

데이터 전달용 클래스이다.

메서드로 getter, setter만 가진다.

public class BookDTO {
	// 변수는 보통 디폴트 혹은 Private을 붙인다. public은 안붙인다. 
	// 디폴트도 다른 패키지에서 사용할 수 있게 getter. setter 붙인다.
	String bookNo;
    String bookTitle;
    String bookAuthor;
    int bookYear;
    int bookPrice;
    String bookPublisher;
    
    // 생성자 
	public BookDTO(String bookNo, String bookTitle, String bookAuthor, int bookYear, int bookPrice,
			String bookPublisher) {
		super();
		this.bookNo = bookNo;
		this.bookTitle = bookTitle;
		this.bookAuthor = bookAuthor;
		this.bookYear = bookYear;
		this.bookPrice = bookPrice;
		this.bookPublisher = bookPublisher;
	}

	// getter, setter
	public String getBookNo() {
		return bookNo;
	}

	public void setBookNo(String bookNo) {
		this.bookNo = bookNo;
	}

	public String getBookTitle() {
		return bookTitle;
	}

	public void setBookTitle(String bookTitle) {
		this.bookTitle = bookTitle;
	}

	public String getBookAuthor() {
		return bookAuthor;
	}

	public void setBookAuthor(String bookAuthor) {
		this.bookAuthor = bookAuthor;
	}

	public int getBookYear() {
		return bookYear;
	}

	public void setBookYear(int bookYear) {
		this.bookYear = bookYear;
	}

	public int getBookPrice() {
		return bookPrice;
	}

	public void setBookPrice(int bookPrice) {
		this.bookPrice = bookPrice;
	}

	public String getBookPublisher() {
		return bookPublisher;
	}

	public void setBookPublisher(String bookPublisher) {
		this.bookPublisher = bookPublisher;
	}

	// 원하는 형식을 출력할 수 있도록 toString 메서드 오버라이딩
	@Override
	public String toString() {
		return bookNo + "\t" + bookTitle + "\t" + bookAuthor 
				+ "\t" + bookYear + "\t" + bookPrice + "\t" +  bookPublisher;
	}

}

 

댓글