DAO

[JDBC] Data Access Object
Jan 23, 2024
DAO
Data Access Object - 데이터베이스와 상호작용하는 오브젝트
SRP - 단일 책임 원칙
위와 같이 사용하면 재사용은 불가능
재사용을 위해 dao 패키지를 만들어 BankDAO 클래스를 만들어준다.

DAO

코드
package dao; import db.DBConnection; import model.Account; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; /** * DAO - Data Access Object * SRP - 단일책임의 원칙 */ public class BankDAO { public int deleteByNumber(int number){ Connection conn = DBConnection.getInstance(); try { String sql ="delete from account_tb where number = ?"; PreparedStatement pstmt = conn.prepareStatement(sql); // 버퍼 pstmt.setInt(1,number); // 쿼리 완성 int num = pstmt.executeUpdate(); // flush return num; } catch (Exception e) { // throw new RuntimeException(e); // 호출자에게 위임 e.printStackTrace(); } return -1; } public int insert(String password, int balance){ Connection conn = DBConnection.getInstance(); try { String sql ="insert into account_tb(password, balance, created_at)" + "values(?,?,now())"; PreparedStatement pstmt = conn.prepareStatement(sql); // 버퍼 pstmt.setString(1,password); pstmt.setInt(2,balance); int num = pstmt.executeUpdate(); return num; } catch (Exception e) { e.printStackTrace(); } return -1; } public int updateByNumber(int balance, int number){ Connection conn = DBConnection.getInstance(); try { String sql ="update account_tb set balance = ? where number = ?"; PreparedStatement pstmt = conn.prepareStatement(sql); // 버퍼 pstmt.setInt(1,balance); pstmt.setInt(2,number); int num = pstmt.executeUpdate(); return num; } catch (Exception e) { e.printStackTrace(); } return -1; } public Account selectByNumber(int number){ Connection conn = DBConnection.getInstance(); try { String sql = "select * from account_tb where number =?"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setInt(1,number); ResultSet rs = pstmt.executeQuery(); if(rs.next()){ // 커서 한칸 내리기 Account account = new Account( rs.getInt("number"), rs.getString("password"), rs.getInt("balance"), rs.getTimestamp("created_at") ); return account; } // System.out.println(isRow); // System.out.println(rs.getInt("number")); // System.out.println(rs.getString("password")); // System.out.println(rs.getInt("balance")); // System.out.println(rs.getTimestamp("created_at")); } catch (Exception e) { e.printStackTrace(); } return null; } public List<Account> selectAll(){ Connection conn = DBConnection.getInstance(); try { String sql = "select * from account_tb order by number desc"; PreparedStatement pstmt = conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery(); List<Account> accountList = new ArrayList<>(); while(rs.next()){ Account account = new Account( rs.getInt("number"), rs.getString("password"), rs.getInt("balance"), rs.getTimestamp("created_at") ); accountList.add(account); } return accountList; } catch (Exception e) { e.printStackTrace(); } return null; } }
Insert, Delete, Update 는 변경된 행의 갯수를 return한다. DAO는 main에 int로 return(따로 파싱이 필요없음)
select는 DB가 DAO에게 table을 return한다. DAO는 main에 자기언어(java object)로 바꿔서 return해줘야함.

Model

model - 테이블과 같은 구조의 Class를 만들어야함.
코드
package model; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.ToString; import java.sql.Timestamp; /** * DB에 select하기 위한 오브젝트 */ @ToString @AllArgsConstructor @Getter public class Account { private int number; private String password; private int balance; private Timestamp createdAt; // java.sql의 Timestamp, 카멜표기법 사용' }
 
BankApp main 코드 잘라내기
BankDAO에 작성

Test

given(파라미터)-when(본코드 실행)-then(검증)
코드
package dao; import model.Account; import org.junit.jupiter.api.Test; import java.util.List; public class BankDAOTest { @Test public void selectAll_test(){ // given // when BankDAO dao = new BankDAO(); List<Account> accountList = dao.selectAll(); System.out.println(accountList.size()); System.out.println(accountList); } @Test public void selectByNumber_test(){ // given int number = 7; // when BankDAO dao = new BankDAO(); Account account = dao.selectByNumber(number); // then if(account == null){ System.out.println(number+"로 조회된 값이 없습니다."); }else{ System.out.println(account); // System.out.println(account.getNumber()); // System.out.println(account.getPassword()); // System.out.println(account.getBalance()); // System.out.println(account.getCreatedAt()); } } @Test public void deleteByNumber_test(){ // given = 파라미터 int number = 4; // when = 본코드 실행 BankDAO dao = new BankDAO(); int result = dao.deleteByNumber(number); // then = 검증 if(result == 1){ System.out.println("삭제 성공"); }else if(result == 0){ System.out.println(number +"번호를 찾을 수 없습니다."); }else { System.out.println("삭제 실패"); } } @Test public void insert_test(){ // given String password = "1234"; int balance = 630000; // when BankDAO dao = new BankDAO(); int result = dao.insert(password, balance); // then if(result == 1){ System.out.println("성공"); }else{ System.out.println("실패"); } } @Test public void updateByNumber_test(){ // given int balance = 0; int number = 3; // when BankDAO dao = new BankDAO(); int result = dao.updateByNumber(balance,number); // then if(result == 1){ System.out.println("업데이트 성공"); }else if(result == 0){ System.out.println(number+"번호를 찾을 수 없습니다."); }else{ System.out.println("업데이트 실패"); } } }

Main

데이터 파싱을 위해 MIME타입 - application/x-www-form-urlencoded
→ 그냥 이거만 쓴다 보면 됨 표준
코드
import dao.BankDAO; import model.Account; import java.sql.SQLOutput; import java.util.List; import java.util.Scanner; public class BankApp { public static void main(String[] args) { Scanner sc = new Scanner(System.in); // 식별자 요청 // GET, DELETE 는 HEAD만 있으면 됨(BODY가 없다), 쿼리 생성가능 // http://bank.com/account GET -> select * from account_tb // http://bank.com/account/1 GET -> select * from account_tb where number = 1; // http://bank.com/account/1 DELETE -> delete from account_tb where number = 1; // PUT, POST는 BODY 데이터가 필요함. // http://bank.com/account/1 PUT // http://bank.com/account POST System.out.println("메서드를 입력하세요"); String method = sc.nextLine(); System.out.println("식별자를 입력하세요"); String action = sc.nextLine(); String body = ""; BankDAO bankDAO = new BankDAO(); if (method.equals("GET")){ // 식별자 끝자리 숫자 String[] st1 = action.split("/"); int number = Integer.parseInt(st1[2]); if(action.equals("/account")){ List<Account> accountList = bankDAO.selectAll(); System.out.println(accountList); }else if(st1.length == 3 && st1[0].isEmpty() && st1[1].equals("account")){ bankDAO.selectByNumber(number); Account account = bankDAO.selectByNumber(number); System.out.println(account); } } else if (method.equals("POST")) { System.out.println("body 데이터를 입력하세요"); body = sc.nextLine(); // password=1234&balance=1000 String[] st1 = body.split("&"); String password = st1[0].split("=")[1]; int balance = Integer.parseInt(st1[1].split("=")[1]); if(action.equals("/account")){ bankDAO.insert(password,balance); } } else if (method.equals("PUT")) { System.out.println("body 데이터를 입력하세요"); body = sc.nextLine(); // balance=1000&number=1 String[] st1 = body.split("&"); int balance = Integer.parseInt(st1[0].split("=")[1]); int number = Integer.parseInt(st1[1].split("=")[1]); if(action.equals("/account")){ bankDAO.updateByNumber(balance,number); } } else if (method.equals("DELETE")){ String[] st1 = action.split("/"); int number = Integer.parseInt(st1[2]); if(st1.length == 3 && st1[0].isEmpty() && st1[1].equals("account")) { bankDAO.deleteByNumber(number); } } } }
 
 
Share article
RSSPowered by inblog