이전 복습 키워드

stack | heap | start() | run() | Thread | Synchronized | DBMS | SQL | Middleware | jdbc | DML | CRUD | DDL | DCL | Transaction | con.setAutoCommit() | rollback() | throw |

첫 날 오후 수업에 설계부터 시작해서 총 삼일에 걸쳐 미니 프로그램을 진행했습니다.

DB와 JDBC를 배우며 크게 복잡하지 않은 기능들을 구현했지만, 수업을 처음 시작했을 때를 생각해보면 감회가 새로운 것 같습니다.

동료 수강생분들 중에는 전공자분들도 계시고, 코딩을 완전히 처음 접해보신 분들도 계십니다. 물론 코딩이 이미 익숙한 분들에게는 지금의 프로그램에 별다른 감흥이 없으실 수도 있겠지만, 저로서는 수업을 시작한 지 한달이 조금 넘은 이 시점에 이런 프로그램을 만들었다는 것에 기쁨과 성취감을 느끼며, 새로운 자극이 되는 것 같습니다.

sun cloud

목차

미니 프로젝트(은행 계좌 프로젝트)

sun cloud


프로그램을 만들기 전에 먼저 요구사항을 분석, 설계한 뒤 프로그램을 구현하도록 하겠습니다.

요구사항분석

저희가 만들 프로그램의 명칭은 계좌관리 프로그램입니다.

요구 사항을 살펴보면 아래와 같습니다.

  • 사용자는 계좌 개설이 가능하다.
    • 계좌 개설 시 계좌번호, 계좌주명, 비밀번호, 잔액정보가 저장되어야 한다.
    • 최초 계좌 개설 시 초기 납입액이 1000원 이상이 되어야한다
    • 계좌번호는 유일해야하고 시스템에서 자동 발급하다
  • 잔액조회는 계좌번호가 존재해야하고 계좌번호에 맞는 비밀번호가 일치해야 한다
  • 입금액, 출금액, 계좌이체액은 모두 0원을 초과해야한다
  • 입금 시 계좌번호, 비밀번호가 일치해야 한다
  • 출금 시 계좌번호, 비밀번호가 일치해야하며 잔액 확인 절차가 필요하다(잔액이 부족하면 안되에)
  • 계좌이체 시 송금자 및 수금자의 계좌가 존재해야하고 이체액은 0원을 초과해야하며 송금자의 비밀번호 또한 일치해야하고 송금자의 잔액 확인 절차가 필요하다
    • 송금 및 입금 처리가 정상적으로 수행될 경우에만 이체 처리가 되도록 한다
  • 계좌 잔액이 가장 높은 계좌주명과 잔액을 조회할 수 있다

얼핏 보기에 복잡해 보이는 조건들도 있고, 보자마자 어떤 키워드가 생각나는 조건들도 있으실 겁니다. 저희가 만들어야할 기능들을 추려보자면 아래와 같습니다.

  • 주요 업무:
    1. 계좌 개설
    2. 잔액 조회
    3. 입금
    4. 출금
    5. 계좌 이체
    6. 보유잔액 가장 높은 계좌 정보 조회(서브쿼리 연습)


설계

수업 중에는 제공된 요구사항을 토대로 조별 토의를 진행하였으며 주요 기능을 간략하게 도출해내고, 이를 토대로 starUML 프로그램을 사용해서 Class Diagram으로 설계했습니다.
한 번에 완성시키지 않고, 단계별로 진행 상황에 맞게 수정하면서 진행했습니다.

첫 번째 단계입니다.

image

DB에 입력할 데이터(테이블)는 bank-project.sql파일에 작성할텐데 현재 다이어그램 상에는 나타나지 않습니다.
테이블에서 사용되는 컬럼값에 매칭되는 변수들을 AccountVO 클래스에 작성했습니다.
accountNo가 계좌번호이자 SQL에서는 pk값이며 계좌주명은 name, 비밀번호는 password, 잔액은 balance로 이름지었습니다.

AccountDAO가 기능을 담는 클래스인데, 현재 시점에서는 계좌개설, 잔액조회 기능과 입금 기능은 메서드명만 구성해 놓았습니다. 추후 프로그램을 만들면서 차근차근 설계를 완성할 예정입니다.

그리고 단위테스트를 진행하기 위해 TestUnit1, TestUnit2 파일이 있는데, 이 역시 기능마다 단위테스트를 진행해야하기 때문에 추가 작성이 필요한 부분이고 아래 세 개의 Exception은 현재 시점에 떠올릴 수 있는 예외 상황 처리를 위한 Exception 클래스들을 미리 설정했습니다.


sun cloud



기능구현

본격적으로 기능을 구현해보도록 하겠습니다.
바로 자바 프로그램을 작성하기 전에 먼저 SQL 파일을 생성해서 테이블을 작성하고 시퀀스를 만들어줘야 자바에서도 DB와 연결해서 사용할 수 있겠죠?

1
2
3
4
5
6
7
create table account(
	account_no number primary key,
	name varchar2(100) not null,
	password varchar2(100) not null,
	balance number not null
)
create sequence account_seq;

계좌 번호를 pk로 설정해주고 시퀀스를 바로 만들어주면 기본 생성은 마쳤습니다.
자바 프로그램 작성에 앞서 단위테스트 또한 진행해야 하니 계좌 생성 부분만 확인해보고 넘어가도록 하겠습니다.

1
insert into account(account_no,name,password,balance) values(account_seq.nextval,'아이유','1234',1000);

시퀀스 부분에 유의해서 작성합니다.

1. 계좌 개설

이제 자바로 넘어오겠습니다.

메서드 작성 전에 우선 기본적으로 생성해야할 파일들을 만들도록 하겠습니다.

image


class diagram에서 보셨다시피 메인 클래스 파일은 test파일에서 단위테스트를 진행하고, AccountVOAccountDAO를 만들어야 합니다.
그리고 DB와의 연결을 위한 정보를 인터페이스로 만들어서 DbInfo에 저장하도록 하겠습니다.

첫번째로 TestUnit1에서 계좌 개설 기능을 테스트하겠습니다.

계좌를 개설할 때 고려해야 할 사항은 세 가지입니다.

  1. 계좌번호, 계좌주명, 비밀번호, 잔액정보가 저장되어야 합니다.
  2. 최초 계좌 개설 시 초기 납입액이 1000원 이상이어야 합니다.
  3. 계좌번호는 유일해야하고 시스템에서 자동 발급합니다.

위 사항들을 모두 만족할 수 있도록 입력값을 다르게 하여 TestUnit1에서 테스트를 진행합니다.

우선 AccountVO에서는 기존에 해왔던 것처럼 인스턴스 변수를 만들고 생성자와 게터, 세터, toString()을 생성합니다.
추가적으로 생성자를 만들 때 필요에 맞게 기본생성자와 accountNo를 제외한 세 개의 매개변수를 갖는 생성자를 만들어두면 나중에 다양한 메서드에서 필요에 맞게 호출할 수 있습니다.
(종종 기본 생성자도 생성하곤 하는데 빈 객체를 생성함으로써 get, set을 이용해 자유롭게 값을 할당해주기 위함입니다. 주로 1개의 값을 필요로 할 때 많이 사용합니다.)


AccountVO 전체 코드
carbon


AccountDAO에서 기능을 구현해보겠습니다.

전에 예제를 진행했던 것처럼 우선 Driver loading을 한 뒤 closeAll()메서드를 여러 번 사용하기에 미리 만들어줍니다.

그리고나서 저희가 목표로 하는 기능을 구현하도록 합니다.

sql문을 먼저 작성해서 테스트한 뒤 메서드를 작성하게 되는데, 계좌 개설에 예외 상황이 있기 때문에 우선 처리해주도록 합니다.
왜냐하면 계좌 개설 시 초기 납입금이 1000원이 안될 경우 더 이상의 진행이 필요가 없기 때문에 먼저 처리를 해주도록 합니다.
그래서 저희가 직접 Exceptionextends하는 Exception class를 만들어서 저희가 지정하는 메세지를 반환하도록 만들어줍니다.
이를 활용해서 계좌정보에서 balance가 1000보다 작을 경우 Exceptionthrow하게 해줍니다.

예외 상황이 처리가 되었다면 그 뒤로는 먼저 테스트해본 sql문에 맞게 코드를 작성해주시면 됩니다.

계좌 개설은 반환값이 필요치 않기에 ResultSet을 사용하지 않고, sql문의 치환문자의 순서에 유의하여 진행해주시면 됩니다.

carbon



2. 잔액 조회

두번째 기능인 계좌 조회 메서드를 만들어보겠습니다.

이번에도 조건을 다시 한 번 살펴보겠습니다.

  • 계좌번호가 존재해야 합니다
  • 계좌번호에 해당하는 비밀번호가 정확해야 합니다

위 두 가지 예외 상황을 확인하기 위해 테스트 클래스에서 아래와 같이 진행합니다.

  • 존재하지 않는 계좌번호 입력
  • 잘못된 비번입력

이렇게 잘못된 입력 시 예외가 올바르게 처리되어야 저희가 목표로 하는 기능을 온전히 구현할 수 있습니다.

이제 SQL문 테스트를 해보고 기능 구현에 들어갈텐데, 저는 처음에 위 조건을 보고 balance(잔액)를 조회하되 계좌번호와 비밀번호가 특정한 조건을 생각하고 풀이를 진행해서 어려움을 겪었던 것 같습니다.

SELECT balance FROM account WHERE accountNo=? AND password=?; 이렇게 생각을 했습니다.

if(rs.next)구문에서 계좌번호나 비밀번호가 불일치하다면 exception을 발생시킬 생각이었는데, 제대로 적용이 되지 않았고, 그 다음으로는 list에 값들을 집어넣어서 내용 일치를 확인할 생각이었는데 이 역시 상당히 번거롭고 iterator를 사용해서 contains 기능을 활용하려 했지만 컴파일 에러가 발생했습니다.

어디서 잘못되었을까 고민을 하던 찰나에 강사님께서 힌트를 제공해주셨는데(사실상 정답을 알려주신 것과 다름 없던 것 같습니다) SQL문에서 password와 balance를 조회하고 계좌번호를 조건문으로 사용하면 된다고 하셔서 아차 싶은 생각에 작성해보니 정상적으로 작동을 하는 것을 확인했습니다.

carbon

8번 라인을 보시면 sql문을 확인하실 수 있는데 balance만을 조회하는 것이 아니라 저희가 할당한 account_no와 일치하는 passwordbalance를 같이 조회하는 것이 관건이었습니다.
이렇게 함으로써 12번 라인~ 20번 라인까지의 코드를 구성할 수 있게 됩니다.

해당 결과가 반환된다면 계좌번호가 존재한다는 의미이고, 여기서 다시 password의 일치 여부를 판단해서 일치하지 않을 경우 exceptionthrow해주고 일치한다면 balance를 반환하도록 합니다.
계좌번호가 존재하지 않는다면 그에 맞게 exceptionthrow해주면 됩니다.


이번 글에서는 두번째 기능까지만 구현해보도록 하고 다음 글에서 남은 기능들을 구현해보고 class diagram도 업데이트 해보도록 하겠습니다.

Database 카테고리 내 다른 글 보러가기

댓글남기기