▶ DTO (Data Transfer Object )
VO(Valued Object)나 Beans라고도 불리며
데이터를 저장하고 관리하는 클래스로,
데이터 자체라고도 볼 수 있으며,
테이블의 컬럼과 비슷한 구성의 멤버변수를 가지고 있고,
멤버변수는 private으로 보호되며,
클래스 외부에서는 public getter/setter를 통해 멤버변수에 접근하고 수정할 수 있다.
▶ DAO (Data Access Object)
데이터 베이스와 관련된 작업을 모아놓은 클래스로,
입력, 수정, 검색, 삭제 등의 작업(CRUD)을 정의해서 캡슐화 해놓은 클래스이다
이론이랄게 없다.. 실습을 최대한 많이 하면서 내껄로 만들어보자
아좌좟
테이블에 입력, 수정, 삭제 등의 작업을 하기위해서는
1. 드라이버 로딩 클래스 (DBUtil)
2. DTO
3. DAO
4. Manager
5. console
이렇게 총 5개의 클래스를 쌓아가며 만들어줘서 작업해야깔끔하다.
대표예제 ) pd테이블을 이용하여
[ 1.등록 2.수정 3.삭제 4.전체조회 5.번호로조회 6.이름으로 조회 7.종료 ] 작업을 수행해라
DAO, DTO 이용
▽ pd table
[1] DBUtil
- 드라이버 로딩 단계는 코드가 동일하기때문에
작업을 할때마다 처음부터 작성할 필요가 없다.
클래스로 만들어서 사용하도록 하자.
package com.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DBUtil {
//static초기화 블럭
static {
//1. 드라이버 로딩
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
System.out.println("드라이버 로딩 성공");
} catch (ClassNotFoundException e) {
System.out.println("드라이버 로딩 실패!");
e.printStackTrace();
}
}
public static Connection getConnection(String url, String user,
String pwd) throws SQLException {
//2. 데이터베이스 서버에 연결하기 위한 Connection객체 생성
Connection con=DriverManager.getConnection(url, user, pwd);
System.out.println("db연결, con="+con);
return con;
}
public static Connection getConnection() throws SQLException {
//2. 데이터베이스 서버에 연결하기 위한 Connection객체 생성
String url="jdbc:oracle:thin:@---------------:1521:xe";
String user="javauser", pwd="---------";
Connection con=getConnection(url, user, pwd);
return con;
}
public static Connection getConnection(String user, String pwd)
throws SQLException {
String url="jdbc:oracle:thin:@DESKTOP-56VTHAK:1521:xe";
Connection con = getConnection(url, user, pwd);
return con;
}
public static void dbClose(ResultSet rs, PreparedStatement ps,
Connection con) throws SQLException {
if(rs!=null) rs.close();
if(ps!=null) ps.close();
if(con!=null) con.close();
}
public static void dbClose(PreparedStatement ps,
Connection con) throws SQLException {
if(ps!=null) ps.close();
if(con!=null) con.close();
}
}
- getConnection 메서드를 오버로딩해서
url, user, pwd 가 매개변수로 있을 때 con 객체생성,
user, pwd 가 매개변수로 있을때 ``
url, user, pwd 가 지정되어있을 때 ``
- dbClose 메서드를 오버로딩해서
rs, ps , con 객체가 매개변수로 있을 때 dbclose
ps, con 객체가 매개변수로 있을 때 dbclose
[2] DTO
DTO(Data Transfer Object), VO(Value Object), Bean
객체를 표현한 한 단위
데이터를 전달하는 단위
빈즈 규약(캡슐화된 객체)
- 멤버변수는 private으로
- 멤버변수에 대한 접근은 getter/setter로
package com.pd.model;
import java.sql.Timestamp;
public class PdDTO {
//1. private 멤버변수
private int no;
private String pdName; //마우스
private int price; //19000
private Timestamp regdate;
//2. 생성자
public PdDTO() {
super();
}
public PdDTO(int no, String pdName, int price, Timestamp regdate) {
super();
this.no = no;
this.pdName = pdName;
this.price = price;
this.regdate = regdate;
}
//3. getter/setter
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getPdName() {
return pdName;
}
public void setPdName(String pdName) {
this.pdName = pdName;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public Timestamp getRegdate() {
return regdate;
}
public void setRegdate(Timestamp regdate) {
this.regdate = regdate;
}
//4. toString()
@Override
public String toString() {
return "PdDTO [no=" + no + ", pdName=" + pdName + ", price=" + price + ", regdate=" + regdate + "]";
}
}
△ 우클릭 해서 source 들어가면 생성자 / getter setter / toString 뚝딱뚝딱 생성할 수 있삼
[3] DAO
데이터베이스 작업을 전담하는 객체
CRUD
C : create, insert
R : read, select
U : update
D : delete
★ 유형별 사용형식 ★
▷ 유형 1 : 입력, 수정시 (select , update ) : 매개변수가 DTO 인 유형을 사용한다
- pd 테이블에 입력
public int insertPd(PdDTO dto) throws SQLException {
Connection con=null;
PreparedStatement ps=null;
try {
//1, 2
con=DBUtil.getConnection(); // ■
//3
String sql="insert into pd(no, pdname, price)"
+ " values (pd_seq.nextval, ?,?)";
ps=con.prepareStatement(sql);
ps.setString(1, dto.getPdName()); //■
ps.setInt(2, dto.getPrice()); //■
//4
int cnt=ps.executeUpdate(); //■
System.out.println("상품 등록 결과 cnt="+ cnt+", 매개변수 dto="+dto);
return cnt;
}finally {
DBUtil.dbClose(ps, con);
}
}
■ con : DBUtil 에서 만든 드라이버로딩 메서드 getconnection 을 con 객체에 넣어 db연결
■ dto.getPdName() : DTO에서 PdName은 private 으로 지정되어있기때문에 다른 클래스로 값을 가져올 수 없다.
따라서 getter 을 이용해서 값을 가져온 것
■ ps.setInt(2, dto.getPrice()) : 두번째 물음표에 dto에서 price 를 get 해서 넣어라.
■ executeUpdate :반영된 레코드의 건수를 반환
▷ 유형 2 : select 결과 레코드가 하나인 경우 : 반환타입이 DTO인 유형을 사용한다
- 상품번호를 입력하면 해당 상품번호의 정보가 출력됨
public PdDTO selectByNo(int no) throws SQLException {
Connection con=null;
PreparedStatement ps=null;
ResultSet rs=null;
PdDTO dto = new PdDTO(); //■
try {
//1,2 con
con=DBUtil.getConnection();
//3.ps
String sql="select * from pd where no=?";
ps=con.prepareStatement(sql);
ps.setInt(1, no);
//4. exec
rs=ps.executeQuery(); // ■
if(rs.next()) {
int price=rs.getInt("price");
String pdName=rs.getString("pdname");
Timestamp regdate=rs.getTimestamp("regdate");
dto.setNo(no); // ■
dto.setPdName(pdName);
dto.setPrice(price);
dto.setRegdate(regdate);
}
System.out.println("번호로 조회 결과 dto="+dto+", 매개변수 no="+no); // ■
return dto;
}finally {
DBUtil.dbClose(rs, ps, con);
}
}
■ PdDTO dto = new PdDTO() : 결과 레코드 하나를 DTO로 묶어서 리턴하려는 용도
■ executeQuery() : 수행결과로 ResultSet 객체의 값을 반환. 따라서 ResultSet 객체에 결과값을 담는다
■ dto.setNo(no) : 하나의 레코드는 하나의 DTO . 컬럼의 값들을 DTO에 넣어서 DTO 하나를 리턴한다
■ 번호로 조회 결과 dto="+dto : dto클래스의 toString 메서드가 호출됨
- ex ) [no=3, pdName=핸드폰, price=100000, regdate=2022-04-01 20:02:19.0]
▷ 유형 3 : select 결과 레코드가 여러개인 경우 : 반환타입이 List인 유형을 사용한다 !
- 상품명을 입력하면 입력된 상품명에 해당하는 모든 상품의 정보가 출력됨
public List<PdDTO> selectAll() throws SQLException {
Connection con=null;
PreparedStatement ps=null;
ResultSet rs=null;
List<PdDTO> list = new ArrayList<PdDTO>(); // ■
try {
//1,2 con
con=DBUtil.getConnection();
//3. ps
String sql="select * from pd order by no desc";
ps=con.prepareStatement(sql);
//4. exec
rs=ps.executeQuery();
while(rs.next()) {
int no=rs.getInt(1);
String pdName=rs.getString(2);
int price=rs.getInt(3);
Timestamp regdate=rs.getTimestamp(4); // ■
//[1] 하나의 레코드를 DTO로 묶어준다
PdDTO dto = new PdDTO(no, pdName, price, regdate);
//[2] 여러개의 DTO를 list로 묶는다
list.add(dto);
}
System.out.println("상품전체 조회 결과 list.size="+list.size());
return list;
}finally {
DBUtil.dbClose(rs, ps, con);
}
}
■ List<PdDTO> list = new ArrayList<PdDTO>() : 여러 개의 레코드(DTO)를 list로 묶어서 리턴하려는 용도
■ rs 객체가 있는동안 rs 객체의 컬럼들을 가져와 각각 변수에 담은 후 DTO 로 묶어준다
★★★ 순서 : [1] 하나의 레코드를 DTO로 묶어준다 => [2] 여러개의 DTO를 list로 묶는다
▷ 수정할 상품번호를 입력해면 해당 상품번호의 이름과 가격을 수정해주는
updatePd 메서드
= > select, update는 매개변수가 DTO 인 유형을 사용
public int updatePd(PdDTO dto) throws SQLException {
Connection con= null;
PreparedStatement ps= null;
try {
con=DBUtil.getConnection();
String sql="update pd set pdname=? , price=? where no=? ";
ps= con.prepareStatement(sql);
ps.setString(1,dto.getPdName());
ps.setInt(2,dto.getPrice() );
ps.setInt(3,dto.getNo()); // ■
int cnt= ps.executeUpdate();
System.out.println("상품 수정결과 cnt="+cnt +", 매개변수 dto="+dto);
return cnt;
}finally{
DBUtil.dbClose(ps, con);
}
}
■ DTO 의 PdName 을 가져와서 1번째 물음표에 set 해라
▷ 상품명을 입력하면 입력된 이름에 해당하는 상품정보를 출력해주는
selectByName 메서드
상품명을 중복될 수 있다 . 따라서 select 결과 레코드가 여러개인 경우에 해당한다
=> 반환타입이 List인 유형을 사용
public List<PdDTO> selectByName(String pdName) throws SQLException {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<PdDTO> list = new ArrayList<PdDTO>();
try {
//1,2
con = DBUtil.getConnection();
//3
String sql="select * from pd where pdName = ?";
ps=con.prepareStatement(sql);
ps.setString(1, pdName);
//4
rs=ps.executeQuery();
while(rs.next()) {
int no=rs.getInt(1);
int price=rs.getInt(3);
Timestamp regdate=rs.getTimestamp(4);
//[1]
PdDTO dto = new PdDTO(no, pdName, price, regdate);
//[2]
list.add(dto); // ■
}
System.out.println("이름으로 조회 결과 list.size="+list.size()
+ ", 매개변수 pdName="+ pdName);
return list;
} finally {
DBUtil.dbClose(rs, ps, con);
}
}
■ [1] 하나의 레코드를 DTO로 묶어준다 => [2] 여러개의 DTO를 list로 묶는다
▷ 상품번호를 입력하면 입력된 상품번호에 해당하는 상품정보를 지워주는
deletePd 메서드
public int deletePd(int no) throws SQLException {
Connection con=null;
PreparedStatement ps=null;
try {
//1,2 con
con=DBUtil.getConnection();
//3 ps
String sql="delete from pd where no=?";
ps=con.prepareStatement(sql);
ps.setInt(1, no);
//4 exec
int cnt=ps.executeUpdate();
System.out.println("상품 삭제 결과 cnt="+cnt+", 매개변수 no="+no);
return cnt;
}finally {
DBUtil.dbClose(ps, con);
}
}
[4] PdManager
public class PdManager {
private Scanner sc = new Scanner(System.in);
private PdDAO pdDao;
public PdManager(){
pdDao=new PdDAO();
}
public void showAll() throws SQLException {
//1.
//2.
List<PdDTO> list=pdDao.selectAll();
//3.
for(int i=0;i<list.size();i++) {
PdDTO dto=list.get(i);
System.out.println(dto.getNo()+"\t"+dto.getPdName()+"\t"
+ dto.getPrice()+"\t"+dto.getRegdate());
}//for
System.out.println();
}
public void register() throws SQLException {
//1. 사용자 입력 받기
System.out.println("상품명, 가격 입력!");
String pdName=sc.nextLine();
String sPrice=sc.nextLine();
int price=0;
if(sPrice!=null && !sPrice.isEmpty()) {
price=Integer.parseInt(sPrice);
}
//2. db작업
PdDTO dto = new PdDTO();
dto.setPdName(pdName);
dto.setPrice(price);
int cnt=pdDao.insertPd(dto);
//3. 결과 처리
String result=(cnt>0)?"등록 성공":"등록 실패";
System.out.println(result);
}
public void showByNo() throws NumberFormatException, SQLException {
//1. 사용자 입력받기
System.out.println("조회할 번호 입력!");
String sNo=sc.nextLine();
//유효성 검사
if(sNo==null || sNo.isEmpty()) {
System.out.println("번호 입력해야 함!!!");
return;
}
//2. db작업
PdDTO dto=pdDao.selectByNo(Integer.parseInt(sNo));
//3. 결과 처리
System.out.println("번호:"+dto.getNo());
System.out.println("상품명:"+dto.getPdName());
System.out.println("가격:"+dto.getPrice());
System.out.println("등록일:"+dto.getRegdate()+"\n");
}
public void edit() throws SQLException {
//1.
System.out.println("변경할 상품 번호, 상품명, 가격 입력!");
String no= sc.nextLine();
String pName=sc.nextLine();
String price= sc.nextLine();
//2.
PdDTO dto= new PdDTO();
dto.setNo(Integer.parseInt(no));
dto.setPdName(pName);
dto.setPrice(Integer.parseInt(price));
int cnt= pdDao.updatePd(dto);
//3.
String result=(cnt>0)? "상품 수정 성공": "수정 실패";
System.out.println(result);
}
public void showByName() throws SQLException {
//1
System.out.println("제품의 이름을 입력!");
String pdName = sc.nextLine();
//2
List<PdDTO> list=pdDao.selectByName(pdName);
//3
for(PdDTO dto : list) {
System.out.println(dto.getNo()+"\t"+dto.getPdName()+"\t"
+ dto.getPrice()+"\t"+ dto.getRegdate());
}
System.out.println();
}
public void delete() throws NumberFormatException, SQLException {
//1
System.out.println("삭제할 번호 입력!");
String no=sc.nextLine();
if(no==null || no.isEmpty()) {
System.out.println("번호 입력해야 함!!");
return;
}
//2
int cnt=pdDao.deletePd(Integer.parseInt(no)); //커서 올려서 메서드 반환타입 확인 후 반환값지정 !!
//3
String result="";
if(cnt>0) {
result="상품 삭제 성공";
}else {
result="상품 삭제 실패";
}
System.out.println(result);
}
}
메서드마다 코드해석해야하는데 ,, 저 지금 과제하러 가야됨요 시간날때 작성함
[5] PdConsole
package com.jdbc.day3;
import java.sql.SQLException;
import java.util.Scanner;
public class PdConsole2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
PdManager manager = new PdManager();
while(true) {
System.out.println("1.등록 2.수정 3.삭제 4.전체조회 5.번호로조회 "
+ "6.이름으로 조회 7.종료");
int type=sc.nextInt();
switch(type) {
case 1:
try {
manager.register();
} catch (SQLException e) {
e.printStackTrace();
}
break;
case 2:
try {
manager.edit();
} catch (SQLException e1) {
e1.printStackTrace();
}
break;
case 3:
try {
manager.delete2();
} catch (NumberFormatException | SQLException e1) {
e1.printStackTrace();
}
break;
case 4:
try {
manager.showAll();
} catch (SQLException e) {
e.printStackTrace();
}
break;
case 5:
try {
manager.showByNo();
} catch (SQLException e) {
e.printStackTrace();
}
break;
case 6:
try {
manager.showByName();
} catch (SQLException e) {
e.printStackTrace();
}
break;
case 7:
System.out.println("시스템 종료함!");
System.exit(0);
default:
System.out.println("잘못 선택!\n");
}
}//while
}
}
'JAVA' 카테고리의 다른 글
[JAVA] AWT.EVENT (0) | 2022.04.06 |
---|---|
[JAVA] AWT (0) | 2022.04.05 |
[JDBC] 오라클 developer - JAVA eclipse 연동 / JDBC 프로그래밍 순서 (0) | 2022.04.01 |
[JAVA] 형식화클래스 / Math 클래스의 메서드 / StringBuffer / StringTokenizer / 연산자 == (0) | 2022.03.15 |
[JAVA] TreeSet / String , Calendar, Date 클래스의 메서드 (0) | 2022.03.13 |