본문 바로가기
Spring-Java/JDBC

Day18_JDBC, Banking 예제 1

by 현대타운301 2023. 9. 11.

2023.09.06

 

Day18 네 줄 요약

- DBConnection( ) 클래스의 DBConnect( ) 메소드를 통해 DB 접속

- SQL 관련 객체들은 반드시 try-catch로 감싸야 함 (auto surround 기능 제공)

- 1) INSERT, 2) UPDATE, 3) DELETE의 경우 : int 타입의 변수(여기서는 'rseult')에 숫자를 받아 저장한 후 0보다 큰지 판별

- 4) SELECT의 경우 : ResultSet 객체(여기서는 'rs')에 쿼리문의 결과를 받아 저장한 후 rs.get 메소드로 값 저장

 


 

Oracle DB 접속을 위한 DBConnection 클래스 생성

 

DBConnect() 메소드의 type은 'Connection'이기 때문에 리턴 값의 type또한 Connection이다.

 

 

source code

package JDBC;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBConnection {
	// Java-OracleDB 연결 매소드 DBConnect()
	public static Connection DBConnect() {		// static 메소드로 생성하면 객체 생성과정 생략 가능
		Connection con = null;			// static 메소드 호출은 클래스명으로 접근
		
		String user = "ICIA";
		String pw = "1111";
		String url = "jdbc:oracle:thin:@localhost:1521:xe";
		
		try {
			// ojdbc8.jar 파일을 현재 프로젝트에 적용
			Class.forName("oracle.jdbc.driver.OracleDriver");
            // Java는 DriverManager 인터페이스를 통해 DB에 접속
			con = DriverManager.getConnection(url, user, pw);
			System.out.println("DB 접속 성공!");
		} catch (ClassNotFoundException ce) {
			// ojdbc8.jar 파일이 존재하지 않을 경우(오라클 드라이버를 찾지 못 할 경우) 오류가 발생한 경로를 찾아줌
			ce.printStackTrace();
			System.out.println("DB 접속 실패...드라이버 로딩 실패...");
		} catch (SQLException se) {
			// 오라클 계정정보(user, pw, url) 중 하나라도 틀린 경우
			se.printStackTrace();
			System.out.println("DB 접속 실패...DB 접속 정보 오류!");
		}		
		
		return con;
	}
	
}

 


 

JDBC

 

" JDBC(Java DataBase Connectivity)Java SE 에디션과 함께 패키지된

API(Application Program Interface)로,  Java 애플리케이션을

RDBMS(Relational DataBase Management System, 관계형 데이터베이스 관리 시스템)에

연결하는 프로세스를 표준화하고 단순화할 수 있도록 해줍니다. "

https://www.theserverside.com/definition/Java-Database-Connectivity-JDBC

 

JDBC 구성 요소
JDBC API는 데이터베이스에 대한 연결을 나타내고 SQL 쿼리를 데이터베이스에 보내는 기능을 제공하며 Java 개발자가 관계형 데이터베이스 상호 작용의 결과를 처리하는 데 도움을 주는 여러 인터페이스와 클래스로 구성됩니다.

 

  java.sql.Connection   Java 프로그램에서 외부 DB 시스템으로의 연결을 나타냄
  java.sql.Statement   연결된 DB에서 SQL 문을 실행하는 데 사용
  java.sql.PreparedStatement   사전 컴파일된 SQL 문을 연결된 DB에서 실행하는 데 사용
  java.sql.ResultSet   SQL 문이 처리된 후 DB에서 반환된 결과를 나타냄
  java.sql.Blob   이미지나 비디오와 같은 large binary object를 포함하는 DB 파일을 나타냄

 

 

SQL 객체생성

쿼리문의 작성과 결과값 반환에 관련된 객체들은 항상 try-catch로 감싸야 함

해당 객체들은 SQL 관련 클래스(ex. BankSQL, StudentSQL, ...)에서 선언하고 메소드 안에서 사용

 

1) Connection con;

// 1. DB 접속 메소드
    public void connect() {
    /*  DBConnect() 메소드가 static이 아닐 경우,
        DBConnection() 클래스 객체 먼저 생성해야 함
        DBConnection conn = new DBConnection();
        con = conn.DBConnect();
     */
        con = DBConnection.DBConnect();
    }

 

2) PreparedStatement pstmt;

'?(물음표 기호)'를 통해 쿼리문에 매개변수로 받은 값을 저장

물음표 개수만큼 index가 자동으로 1부터 numbering됨

     - pstmt = con.prepareStatement(sql)

          : String sql = "UPDATE ...."; 와 같은 쿼리문 문자열 sqlpstmt에 저장 

     - pstmt.executeUpdate()

          : DB에서 1) INSERT, 2) UPDATE, 3) DELETE 기능을 수행 후, update 완료된 행의 개수를 int type 으로 반환

     - pstmt.executeQuery()

          : DB에서 4) SELECT 기능을 수행 후 조회된 컬럼들의 값을 반환 (rs 객체와 짝꿍)

// 4-2. 입금 메소드
    public void deposit(String cAccount, int money) {
        String sql = "UPDATE BANKCLIENT SET BALANCE = BALANCE + ? WHERE CACCOUNT = ?";
        try {
            pstmt = con.prepareStatement(sql);
            pstmt.setInt(1, money);
            pstmt.setString(2, cAccount);
            int result = pstmt.executeUpdate();

            if (result > 0) {
                System.out.println("입금 성공!");
            } else {
                System.out.println("입금 실패...");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

 

3) ResultSet rs;

pstmt.executeQuery() 와 짝꿍으로, 조회한 컬럼의 데이터를 반환

     - rs.next() : 조회된 컬럼의 값이 있으면 true, 없으면 false 리턴

     - rs.get___(index) : ___ = 받아오는 값의 type, index = 컬럼의 순서를 입력

// 5-1. 잔액 조회 메소드
    public int getBalance(String cAccount) {
        int balance = 0;
        String sql = "SELECT BALANCE FROM BANKCLIENT WHERE CACCOUNT = ?";
        try {
            pstmt = con.prepareStatement(sql);
            pstmt.setString(1, cAccount);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                balance = rs.getInt(1);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return balance;
    }

 


 

예제 (뱅킹프로그램 Bank)

 

source code

* 코드블럭의 class 순서는 다음과 같고, IntelliJ(인텔리제이) IDE에서 작성 됨

1) DBConnection( ) : DB 연결을 위한 클래스

2) BankClient( ) : 회원정보가 담긴 객체(여기선 'client')를 저장하기 위한 클래스

3) BankSQL( ) : SQL 관련 객체를 정의하고 main에서 사용할 쿼리문 메소드가 담긴 클래스

4) BankMain( ) : Bank project의 main 클래스

 

package Bank;

// [1] DBConnection
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBConnection {
    public static Connection DBConnect(){
        Connection con = null;

        String user = "ICIA";
        String password = "1111";
        String url = "jdbc:oracle:thin:@localhost:1521:xe";

        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            con = DriverManager.getConnection(url, user, password);
            System.out.println("DB 접속 성공!");
        } catch (ClassNotFoundException | SQLException e) {
            System.out.println("DB 접속 실패...");
            throw new RuntimeException(e);
        }
        return con;
    }
}


// [2] BankClient
public class BankClient {
    // 1. 필드
    private int cNum;
    private String cName;
    private String cAccount;
    private int Balance;

    // 2. 생성자 : default

    // 3. 메소드
    public int getcNum() {
        return cNum;
    }

    public void setcNum(int cNum) {
        this.cNum = cNum;
    }

    public String getcName() {
        return cName;
    }

    public void setcName(String cName) {
        this.cName = cName;
    }

    public String getcAccount() {
        return cAccount;
    }

    public void setcAccount(String cAccount) {
        this.cAccount = cAccount;
    }

    public int getBalance() {
        return Balance;
    }

    public void setBalance(int Balance) {
        this.Balance = Balance;
    }

    @Override
    // 사용은 하지 않음
    public String toString() {
        return "BankClient{" +
                "cNum=" + cNum +
                ", cName='" + cName + '\'' +
                ", cAccount='" + cAccount + '\'' +
                ", balacnce=" + Balance +
                '}';
    }
}


// [3] BankSQL
import java.sql.*;      // sql 관련 객체 선언에 필요한 모든 패키지들을 한 번에 import

public class BankSQL {
    Connection con;
    PreparedStatement pstmt;
    Statement stmt;
    ResultSet rs;

    // 1. DB 접속 메소드
    public void connect() {
    /*  DBConnect() 메소드가 static이 아닐 경우,
        DBConnection() 클래스 객체 먼저 생성해야 함
        DBConnection conn = new DBConnection();
        con = conn.DBConnect();
     */
        con = DBConnection.DBConnect();
    }

    // 2. DB 해제 메소드
    public void conClose() {
        try {
            con.close();
            System.out.println("DB 접속 해제!");
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    // 3-1. 고객번호 생성
    public int clientNum() {
        int cNum = 0;
        String sql = "SELECT MAX(CNUM) FROM BANKCLIENT";
        try {
            pstmt = con.prepareStatement(sql);
            rs = pstmt.executeQuery();

            if (rs.next()) {
                cNum = rs.getInt(1) + 1;
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return cNum;
    }
    // 3-2. 계좌번호 생성
    public String clientAccount() {
        String newAccount = "110-";
        for (int i = 0; i < 3; i++) {
            int account1 = (int)((Math.random() * 9) + 1);
            newAccount += account1;
        }
        newAccount += "-";

        for (int i = 0; i < 6; i++) {
            int account2 = (int)((Math.random() * 9) + 1);
            newAccount += account2;
        }
        return newAccount;
    }
    // 3-3. DB에 정보 저장
    public void clientJoin(BankClient client) {
        String sql = "INSERT INTO BANKCLIENT VALUES(?,?,?,?)";
        try {
            pstmt = con.prepareStatement(sql);
            pstmt.setInt(1, client.getcNum());
            pstmt.setString(2, client.getcName());
            pstmt.setString(3, client.getcAccount());
            pstmt.setInt(4, client.getBalance());
            int result = pstmt.executeUpdate();

            if (result > 0) {
                System.out.printf("%s 님, 계좌생성 완료!\n계좌번호 : %s\n계좌잔액 : %,d원", client.getcName(), client.getcAccount(), client.getBalance());
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    // 4-1. 계좌 유무 확인 메소드
    public boolean checkAccount(String cAccount) {
        boolean check = false;
        String sql = "SELECT * FROM BANKCLIENT WHERE CACCOUNT = ?";
        try {
            pstmt = con.prepareStatement(sql);
            pstmt.setString(1, cAccount);
            rs = pstmt.executeQuery();
            if (rs.next()) {
              check = true;
            } else {
                System.out.println("조회할 수 없는 계좌입니다...");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return check;
    }
    // 4-2. 입금 메소드
    public void deposit(String cAccount, int money) {
        String sql = "UPDATE BANKCLIENT SET BALANCE = BALANCE + ? WHERE CACCOUNT = ?";
        try {
            pstmt = con.prepareStatement(sql);
            pstmt.setInt(1, money);
            pstmt.setString(2, cAccount);
            int result = pstmt.executeUpdate();

            if (result > 0) {
                System.out.println("입금 성공!");
            } else {
                System.out.println("입금 실패...");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    // 5-1. 잔액 조회 메소드
    public int getBalance(String cAccount) {
        int balance = 0;
        String sql = "SELECT BALANCE FROM BANKCLIENT WHERE CACCOUNT = ?";
        try {
            pstmt = con.prepareStatement(sql);
            pstmt.setString(1, cAccount);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                balance = rs.getInt(1);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return balance;
    }
    // 5-2. 출금 메소드
    public void withdraw(String cAccount, int money) {
        String sql = "UPDATE BANKCLIENT SET BALANCE = BALANCE - ? WHERE CACCOUNT = ?";
        try {
            pstmt = con.prepareStatement(sql);
            pstmt.setInt(1, money);
            pstmt.setString(2, cAccount);
            int result = pstmt.executeUpdate();

            if (result > 0) {
                System.out.println("출금 성공!");
            } else {
                System.out.println("출금 실패...");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    // 6. 송금 메소드
    public void transferMoney(String sendAccount, String receiveAccount, int money) {
        String sql1 = "UPDATE BANKCLIENT SET BALANCE = BALANCE - ? WHERE CACCOUNT = ?";
        String sql2 = "UPDATE BANKCLIENT SET BALANCE = BALANCE + ? WHERE CACCOUNT = ?";
        try {
            pstmt = con.prepareStatement(sql1);
            pstmt.setInt(1, money);
            pstmt.setString(2, sendAccount);
            pstmt.executeUpdate();
            pstmt = con.prepareStatement(sql2);
            pstmt.setInt(1, money);
            pstmt.setString(2, receiveAccount);
            int result = pstmt.executeUpdate();

            if (result > 0) {
                System.out.println("송금 성공!");
            } else {
                System.out.println("송금 실패...");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    // 7. 목록 조회 메소드
    public void selectClient() {
        String sql = "SELECT * FROM BANKCLIENT";
        try {
            System.out.println("No.\t\tName\t\tAccount\t\t\t\tBalance");
            pstmt = con.prepareStatement(sql);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                System.out.printf("%d\t\t%s\t\t%s\t\t%,d원\n", rs.getInt(1), rs.getString(2), rs.getString(3), rs.getInt(4));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }

}


// [4] BankMain
import java.util.Scanner;

public class BankMain {
    public static void main(String[] args) {
        BankClient client = new BankClient();
        BankSQL sql = new BankSQL();
        Scanner sc = new Scanner(System.in);
        boolean run = true;

        while (run) {
            System.out.println("=====================라즈베리은행=====================");
            System.out.println("[1]DB접속     [2]DB해제     [3]계좌생성     [4]입금");
            System.out.println("[5]출금       [6]송금       [7]조회        [8]종료");
            System.out.println("=====================================================");
            System.out.print("메뉴선택 > ");
            String menu = sc.next();

            switch (menu) {
                case "1":   // DB 접속
                    sql.connect();
                    break;
                case "2":   // DB 해제
                    sql.conClose();
                    break;
                case "3":   // 계좌생성
                    client.setcNum(sql.clientNum());
                    client.setcAccount(sql.clientAccount());
                    System.out.print("이름 > ");
                    client.setcName(sc.next());
                    System.out.print("초기잔액 > ");
                    client.setBalance(sc.nextInt());
                    sql.clientJoin(client);
                    break;
                case "4":   // 입금
                    System.out.print("입금할 계좌 > ");
                    String inputAccount = sc.next();
                    boolean check = sql.checkAccount(inputAccount);
                    if (check) {
                        System.out.print("입금 금액 > ");
                        int money = sc.nextInt();
                        sql.deposit(inputAccount, money);
                    }
                    break;
                case "5":   // 출금
                    System.out.print("출금할 계좌 > ");
                    inputAccount = sc.next();
                    check = sql.checkAccount(inputAccount);
                    if (check) {
                        System.out.print("출금 금액 > ");
                        int money = sc.nextInt();
                        if (sql.getBalance(inputAccount) < money) {
                            System.out.println("잔액이 부족합니다...");
                        } else {
                            sql.withdraw(inputAccount, money);
                        }
                    }
                    break;
                case "6":   // 송금
                    System.out.print("보내시는 분 계좌 > ");
                    String sendAccount = sc.next();
                    check = sql.checkAccount(sendAccount);
                    if (check) {
                        System.out.print("받으시는 분 계좌 > ");
                        String receiveAccount = sc.next();
                        if (sendAccount.equals(receiveAccount)) {
                            System.out.println("동일한 계좌로의 송금은 진행할 수 없습니다...");
                        } else {
                            boolean checkSA = sql.checkAccount(receiveAccount);
                            if (checkSA) {
                                System.out.print("보내실 금액 > ");
                                int money = sc.nextInt();
                                if (sql.getBalance(sendAccount) < money) {
                                    System.out.println("잔액이 부족합니다...");
                                } else {
                                    sql.transferMoney(sendAccount, receiveAccount, money);
                                }
                            }
                        }
                    }
                    break;
                case "7":   // 조회
                    sql.selectClient();
                    break;
                case "8":   // 종료
                    System.out.println("프로그램 종료...");
                    run = false;
                    break;
                default:
                    System.out.println("1~8중에 입력하세요...");
                    break;
            }
            System.out.println();
        }
    }
}

 

 

Oracle DB

DROP TABLE BANKCLIENT;

CREATE TABLE BANKCLIENT(
    CNUM        NUMBER PRIMARY KEY,
    CNAME       NVARCHAR2(10),
    CACCOUNT    NVARCHAR2(20),
    BALANCE     NUMBER
);

COMMIT;

 

 

 

'Spring-Java > JDBC' 카테고리의 다른 글

Day22_Banking 예제 2  (0) 2023.09.12