본문 바로가기
Study/중앙정보처리학원과정

30일차. DTO(Data Tranfer Object)

by 얏옹이 2022. 12. 5.
반응형

오늘은 DTO에 대해서 강의를 들었다.

 

DAO - Data Access Object 는 데이터베이스의 data에 접근하기 위한 객체이며, 보통 Connection을 위한 기능구현까지만 DAO로 분리해서 설정해주는 경우가 많다.

 

DTO - Data Transfer Object은 계층간 데이터 교환을 위한 Java Beans라고 한다.

데이터베이스의 데이터를 입력하기 위한 데이터 객체 라고 표현할수 있을거같다.

실행을 위한 Main Method나 로직 없이 Field와 Method(Getter, Setter)로 이루어져있는 경우가 많다

즉, 데이터를 입력 혹은 가져오기위해 기능 구현만 한 클래스라고 표현할수 있을것 같다.

 

 

 

2022.12.04 - [Study/중앙정보처리학원과정] - 29일차. DB 클래스화 하기(클래스 다이어그램 맛보기?)

 

29일차. DB 클래스화 하기(클래스 다이어그램 맛보기?)

오늘은 어제 만든 더미 테이블과 더미 데이터들을 기반으로 JAVA 클래스에서 각종 데이터를 입력 수정 삭제 조회 해보는 쿼리문을 Class에 옮겨 필드 및 메소드화 하여 구현하는 수업을 진행했다.

yat-ong.tistory.com

 

이전에 DB 연결 및 쿼리문을 날려주는 동작을 클래스화 해서 이를 ~~~DAO라고 클래스를 명명해놨었다.

 

이걸 다시 DTO로 분리해서 Getter와 Setter를 이용한 값 대입, 가져오기로 코드를 수정해보는 시간이 오늘 주된 강의 내용이였다.

 

먼저 NoticeBoardDTO라는 클래스를 생성하여 필드와 메서드를 생성해주겠다.

 

DB에 있는 값을 토대로 작성해야하니 필드명은 DB의 컬럼명과 일치하게 맞춰주었다.

 

사전에 이러한 DUMMY 테이블과 데이터를 입력을 해놨었고 이를 토대로 DTO 클래스를 생성해주었다.

 

package db.dbEx2;

import java.util.Date;

public class NoticeBoardDTO {
	//field
	private int nbno; //글번호
	private String title; //제목
	private String contant; //내용
	private Date cre_date; //작성일
	private String writer; //작성자
	private int rcnt; //조회수
	private int empno; //회원번호
	
	//constructor
	NoticeBoardDTO() {
		
	}
	
	//method
	public int getNbno() {
		return nbno;
	}
	public void setNbno(int nbno) {
		this.nbno = nbno;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getContant() {
		return contant;
	}
	public void setContant(String contant) {
		this.contant = contant;
	}
	public Date getCre_date() {
		return cre_date;
	}
	public void setCre_date(Date cre_date) {
		this.cre_date = cre_date;
	}
	public String getWriter() {
		return writer;
	}
	public void setWriter(String writer) {
		this.writer = writer;
	}
	public int getRcnt() {
		return rcnt;
	}
	public void setRcnt(int rcnt) {
		this.rcnt = rcnt;
	}
	public int getEmpno() {
		return empno;
	}
	public void setEmpno(int empno) {
		this.empno = empno;
	}

}

 

자 이것이 DTO 클래스의 구성 전부다. 추가로 매개변수가 있는 생성자는 만들어줄수 있지만 일단은 기본생성자만 선언을 해놓았다.

 

이걸 가지고 이제 기존의 DAO 클래스에서 수행문을 수정해주고 수행 로직은 Main 클래스로 좀더 옮겨서 구분화 시켜주겠다.

 

package db.dbEx2;

import java.io.ObjectInputStream.GetField;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

public class NoticeBoardDAO {
	private String sql = "";
	Connection con = JdbcUtil.getConnection();
	PreparedStatement stmt = null;
	
	
	void allSelect() { //전체글조회
		
		
		
		sql = "select nbno,title,contant,cre_date,writer,rcnt,empno" + 
				" from noticeboard order by cre_date desc";
		try {
			stmt = con.prepareStatement(sql);
			ResultSet rs = stmt.executeQuery();
			while(rs.next()) {
				int nbno = rs.getInt("nbno");
				String title = rs.getString("title");
				String contant = rs.getString("contant");
				Date cre_date = rs.getDate("cre_date");
				String writer = rs.getString("writer");
				int rcnt = rs.getInt("rcnt");
				int empno = rs.getInt("empno");
				
				
			System.out.println(nbno+","+title+","+contant+","+cre_date+","+writer+","+rcnt+","+empno);	
			}
			
		} catch (SQLException e) {
			System.out.println("allSelect 실패");
			e.printStackTrace();
		}
	}
	//전체 조회하는 메소드 빼고는 다 NoticeBoardDTO 클래스를 리턴타입으로 갖고 매개변수도 NoticeBoardDTO 타입의 매개변수를 받는 메소드로 수정
	NoticeBoardDTO select(NoticeBoardDTO dto) { //특정글조회 //NoticeBoardDTO 클래스 타입의 dto 참조변수를 매개변수로 받는다
		sql = "select nbno,title,contant,cre_date,writer,rcnt,empno" + 
				" from noticeboard" + 
				" where nbno = ?";
		
		//NoticeBoardDTO 기본생성자 호출 객체 생성
		NoticeBoardDTO nbDto = new NoticeBoardDTO();
		
		try {
			stmt = con.prepareStatement(sql);
			//dto변수안에 있는 값을 get 메소드 호출로 가져와서 쿼리문 ? 에 대입
			stmt.setInt(1, dto.getNbno());
			
			ResultSet rs = stmt.executeQuery();
			
			//단일행 조회기때문에 while보다는 if가 적절
			if(rs.next()) {
				int nbno = rs.getInt("nbno");
				String title = rs.getString("title");
				String contant = rs.getString("contant");
				Date cre_date = rs.getDate("cre_date");
				String writer = rs.getString("writer");
				int rcnt = rs.getInt("rcnt");
				int empno = rs.getInt("empno");
				
				//매개변수가 있는 생성자를 호출해서 객체에 대입
				nbDto = new NoticeBoardDTO(nbno, title, contant, cre_date, writer, rcnt, empno);
			}
			
		} catch (SQLException e) {
			System.out.println("select 실패");
			e.printStackTrace();
		}
		return nbDto; //NoticeBoardDTO 타입의 참조변수 nbDto를 리턴
		
	}
	//전체 조회하는 메소드 빼고는 다 NoticeBoardDTO 클래스를 리턴타입으로 갖고 매개변수도 NoticeBoardDTO 타입의 매개변수를 받는 메소드로 수정
	NoticeBoardDTO insert(NoticeBoardDTO dto) { //등록
		sql = "INSERT INTO noticeboard(nbno,title,contant,cre_date,writer,rcnt,empno)" + 
				" VALUES(NOTICE_SEQ.nextval,?,?,SYSDATE,?,0,7900)";
		NoticeBoardDTO inDto = null; //객체 생성
		try {
			stmt = con.prepareStatement(sql);
			//dto get메소드를 이용하여 private 필드의 값을 가져옴
			stmt.setString(1, dto.getTitle());
			stmt.setString(2, dto.getContant());
			stmt.setString(3, dto.getWriter());
			
			int result = stmt.executeUpdate();
			
			//executeUpdate가 성공한다면 result에 값이 담긴다. 0이라면 쿼리 실패
			if(result != 0) {
				System.out.println(result+"행 입력 완료");
				inDto = dto;
 			} 
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return inDto;
		
		
		
	}
	//전체 조회하는 메소드 빼고는 다 NoticeBoardDTO 클래스를 리턴타입으로 갖고 매개변수도 NoticeBoardDTO 타입의 매개변수를 받는 메소드로 수정
	NoticeBoardDTO update(NoticeBoardDTO dto) { //수정
		sql = "update noticeboard" + 
				" set title = ?, contant = ?, writer=?" + 
				" where nbno = ?";
		NoticeBoardDTO upDto = null;
		try {
			stmt = con.prepareStatement(sql);
			stmt.setString(1, dto.getTitle());
			stmt.setString(2, dto.getContant());
			stmt.setString(3, dto.getWriter());
			stmt.setInt(4, dto.getNbno());
			
			int result = stmt.executeUpdate();
			if(result != 0) {
				System.out.println(result+"행 수정완료");
				upDto = dto;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return upDto;
		
		
	}
	
	NoticeBoardDTO delete(NoticeBoardDTO dto) { //삭제
		sql = "delete noticeboard" + 
				" where nbno = ?";
		
		NoticeBoardDTO deDto = null;
		try {
			stmt = con.prepareStatement(sql);
			stmt.setInt(1, dto.getNbno());
			
			int result = stmt.executeUpdate();
			if(result != 0) {
				System.out.println(dto.getNbno()+"번글 "+result+"건 삭제완료");
				deDto = dto;
				
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return deDto;
		
	}
	
}

 

DTO 클래스를 이용하여 Getter Setter를 값을 대입하고 값을 가져오고를 반복했다.

 

이부분은 조금 복습이 더 필요할거 같다. 아직 수월하게 코드가 적어지질 않는다.

 

다음은 Main 클래스의 수정본이다.

 

package db.dbEx2;

import java.sql.Connection;
import java.util.Scanner;
import java.util.StringTokenizer;

//jdbcutil의 main class
//나중에 웹에선 main method는 불필요
public class Main {
	public static void main(String[] args) {
		NoticeBoardDAO nbd = new NoticeBoardDAO();
		Scanner sc = new Scanner(System.in);
		
		while(true) {
			System.out.println();
			System.out.println("--1.전체조회	2.상세조회	3.등록	4.수정	5.삭제	6.종료");
			System.out.print("메뉴 번호를 입력하세요▶");
			int input = sc.nextInt();
			if(input == 1) {
				nbd.allSelect();
			} else if(input == 2) { //상세조회
				System.out.print("조회할 글번호를 입력하세요▶");
				int nno = sc.nextInt();
				NoticeBoardDTO dto = new NoticeBoardDTO(); //객체 생성
				dto.setNbno(nno); // 입력받은 값을 set메소드로 dto에 대입
				NoticeBoardDTO resultDTO = nbd.select(dto); //Select 메소드에 dto타입의 매개변수를 받도록 수정, 메소드를 수행하고 반환받은 NoticeBoardDTO 클래스를 다시 resultDTO로 받는다.
				System.out.println(resultDTO.getNbno()+","+resultDTO.getTitle()+","+resultDTO.getContant()+","+resultDTO.getCre_date()+","+resultDTO.getWriter()+","+resultDTO.getRcnt()+","+resultDTO.getEmpno());
			} else if(input == 3) {
				NoticeBoardDTO dto = new NoticeBoardDTO();
				System.out.println("등록할 값을 입력해주세요");
				System.out.print("제목:");
				dto.setTitle(sc.next()); 
				System.out.print("내용:");
				dto.setContant(sc.next());
				System.out.print("작성자:");
				dto.setWriter(sc.next());
				NoticeBoardDTO resultDTO = nbd.insert(dto);
				System.out.println(resultDTO.getTitle()+","+resultDTO.getContant()+","+resultDTO.getWriter()+"입력 완료");
			} else if(input == 4) {
				NoticeBoardDTO dto = new NoticeBoardDTO();
				System.out.print("수정할 글번호를 입력하세요▶");
				dto.setNbno(sc.nextInt());
				System.out.print("제목:");
				dto.setTitle(sc.next());
				System.out.print("내용:");
				dto.setContant(sc.next());
				System.out.print("작성자:");
				dto.setWriter(sc.next());
				NoticeBoardDTO resultDto = nbd.update(dto);
				System.out.println(resultDto.getNbno()+"번글 수정완료");
			} else if(input == 5) {
				NoticeBoardDTO deDto = new NoticeBoardDTO();
				System.out.print("삭제할 글번호를 입력하세요▶");
				deDto.setNbno(sc.nextInt());
				NoticeBoardDTO resultDTO = nbd.delete(deDto);
				System.out.println(resultDTO.getNbno()+"번글 삭제 완료");
			} else if(input == 6) {
				JdbcUtil.close(nbd.con);
				JdbcUtil.close(nbd.stmt);
				System.out.println("종료합니다");
				break;
			} else {
				System.out.println("유효하지 않은 명령어입니다.");
			}
				
		}
		
	}
}

 

메인클래스도 보면 Get과 Set으로 값을 대입하고, 리턴받은 DTO 클래스를 다시 Main 클래스에서 다시 빈 객체를 생성하여 리턴값을 받고, 그 값을 받은 참조변수로 다시 값을 뿌려준다.

 

Main클래스의 로직을 실행해보면

 

 

이런식으로 잘 수행된다. DTO 클래스에 관해서는 좀더 연습이 필요한 시점인거 같다.

 

여기서 잘 붙잡고 내것으로 만들어야 앞으로 있을 JSP나 SPRING이 수월해질테니...

 

내일은 ArrayList를 이용해서 추가로 DTO에 대해서 더 보완강의가 이어질거 같다. 화이팅하자!

반응형