1. 초기 데이터 수정 처리
2. withdrawForm.jsp 주소 설계 및 name 속성 확인
3. AccountController 출금 인증 검사, 유효성 검사 추가
4. AccountService 출금 기능 구현 및 트랜잭션 처리
5. MyBatis 맵퍼 확인 및 쿼리 확인
출금 페이지 화면
데이터 초기화 값 수정
INSERT INTO user_tb(username, password, fullname, created_at) values('길동', '1234',
'고', now());
INSERT INTO user_tb(username, password, fullname, created_at) values('둘리', '1234',
'애기공룡', now());
INSERT INTO user_tb(username, password, fullname, created_at) values('콜', '1234',
'마이', now());
INSERT INTO user_tb(username, password, fullname, created_at) values('홍아', '1234',
'항아', now());
INSERT INTO account_tb(number, password, balance, user_id, created_at)
values('1111', '1234', 1200, 1, now());
INSERT INTO account_tb(number, password, balance, user_id, created_at)
values('2222', '1234', 2200, 2, now());
INSERT INTO account_tb(number, password, balance, user_id, created_at)
values('3333', '1234', 0, 3, now());
-- 이체 내역을 기록 ( 1번 계좌에서 2번 계좌로 100원을 이체 한다)
INSERT INTO history_tb(amount, w_balance, d_balance,
w_account_id, d_account_id, created_at)
VALUES (100, 800, 1200, 1, 2, now());
-- 출금 내역 ( 1번계좌에서 100원을 출금 처리 )
INSERT INTO history_tb(amount, w_balance, d_balance,
w_account_id, d_account_id, created_at)
VALUES (100, 700, null, 1, null, now());
-- 입금 내역 (1번 계좌에 500원 입금 처리 )
INSERT INTO history_tb(amount, w_balance, d_balance,
w_account_id, d_account_id, created_at)
VALUES (500, null, 1200, null, 1, now());
-- 입금 내역 (2번 계좌에 1000원 입금 처리 )
INSERT INTO history_tb(amount, w_balance, d_balance,
w_account_id, d_account_id, created_at)
VALUES (100, null, 2200, null, 2, now());
출금 페이지 인증 처리 코드 추가
AccountController
// 출금 페이지
@GetMapping("/withdraw")
public String withdraw() {
User principal = (User)session.getAttribute(Define.PRINCIPAL);
if(principal == null) {
throw new UnAuthorizedException("로그인 먼저 해주세요", HttpStatus.UNAUTHORIZED);
}
return "/account/withdrawForm";
}
AccountController
... 생략
// 출금 처리 기능
@PostMapping("/withdraw-proc")
public String withdrawProc(WithdrawFormDto withdrawFormDto) {
User principal = (User)session.getAttribute(Define.PRINCIPAL);
if(principal == null) {
throw new UnAuthorizedException("로그인 먼저 해주세요", HttpStatus.UNAUTHORIZED);
}
if(withdrawFormDto.getAmount() == null) {
throw new CustomRestfullException("금액을 입력 하세요", HttpStatus.BAD_REQUEST);
}
if( withdrawFormDto.getAmount().longValue() <= 0) {
throw new CustomRestfullException("출금액이 0원 이하일 수는 없습니다", HttpStatus.BAD_REQUEST);
}
if(withdrawFormDto.getWAccountNumber() == null ||
withdrawFormDto.getWAccountNumber().isEmpty()) {
throw new CustomRestfullException("계좌 번호를 입력해주세요", HttpStatus.BAD_REQUEST);
}
if(withdrawFormDto.getWAccountPassword() == null ||
withdrawFormDto.getWAccountPassword().isEmpty()) {
throw new CustomRestfullException("계좌 비밀 번호를 입력해주세요", HttpStatus.BAD_REQUEST);
}
accountService.updateAccountWithdraw(withdrawFormDto, principal.getId());
return "redirect:/account/list";
}
}
AccountService 출금 기능 추가
... 생략
// 출금 기능 로직 고민해 보기
// 1. 계좌 존재 여부 확인 -> select query
// 2. 본인 계좌 여부 확인 ->
// 3. 계좌 비번 확인
// 4. 잔액 여부 확인
// 5. 출금 처리 -> update query
// 6. 거래 내역 등록 -> insert query
// 7. 트랜잭션 처리
@Transactional
public void updateAccountWithdraw(WithdrawFormDto withdrawFormDto, Integer principalId) {
Account accountEntity = accountRepository.findByNumber(withdrawFormDto.getWAccountNumber());
// 1
if(accountEntity == null) {
throw new CustomRestfullException("해당 계좌가 없습니다", HttpStatus.BAD_REQUEST);
}
// 2
if(accountEntity.getUserId() != principalId) {
throw new CustomRestfullException("본인 소유 계좌가 아닙니다", HttpStatus.UNAUTHORIZED);
}
// 3
if(accountEntity.getPassword().equals(withdrawFormDto.getWAccountPassword()) == false) {
throw new CustomRestfullException("출금 계좌 비밀번호가 틀렸습니다", HttpStatus.UNAUTHORIZED);
}
// 4
if(accountEntity.getBalance() < withdrawFormDto.getAmount()) {
throw new CustomRestfullException("계좌 잔액이 부족 합니다", HttpStatus.BAD_REQUEST);
}
// 5 (모델 객체 상태값 변경 처리)
accountEntity.withdraw(withdrawFormDto.getAmount());
accountRepository.updateById(accountEntity);
// 6 거래 내역 등록
History history = new History();
history.setAmount(withdrawFormDto.getAmount());
history.setWBalance(accountEntity.getBalance()); // !!
history.setDBalance(null);
history.setWAccountId(accountEntity.getId());
history.setDAccountId(null);
int resultRowCount = historyRepository.insert(history);
if(resultRowCount != 1) {
throw new CustomRestfullException("정상 처리 되지 않았습니다", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
... 생략
Account 모델 클래스 확인
package com.tenco.bank.repository.model;
import java.sql.Timestamp;
import lombok.Data;
/**
* 모델 클래스 (Value Object 역할만 하는것은 아니다)
*/
@Data
public class Account {
private Integer id;
private String number;
private String password;
private Long balance;
private Integer userId;
private Timestamp createdAt;
public void withdraw(Long amount) {
this.balance -= amount;
}
public void deposit(Long amount) {
this.balance += amount;
}
// 패스워드 체크
// 잔액 여부 확인 (출금시)
// 계좌 소유자 확인
}
History 모델 클래스 확인
package com.tenco.bank.repository.model;
import java.sql.Timestamp;
import lombok.Data;
@Data
public class History {
private Integer id;
private Long amount;
private Long wBalance;
private Long dBalance;
private Integer wAccountId;
private Integer dAccountId;
private Timestamp createdAt;
}
AccountRepository 기능 추가
@Mapper // mybatis 연결 처리
public interface AccountRepository {
... 생략
public Account findByNumber(String number);
}
HistoryRepository 코드 확인
@Mapper // 반드시 지정하기 !
public interface HistoryRepository {
public int insert(History history);
... 생략
}
account.xml
<select id="findByNumber" resultType="com.tenco.bank.repository.model.Account">
select * from account_tb where number = #{number}
</select>
history.xml
<insert id="insert"
parameterType="com.tenco.bank.repository.model.History">
insert into
history_tb(
amount, w_balance, d_balance,
w_account_id, d_account_id
)
values(
#{amount}, #{wBalance}, #{dBalance},
#{wAccountId}, #{dAccountId}
)
</insert>
: 로직 검사 확인
'Spring boot > spring boot 앱 만들어 보기 2 단원' 카테고리의 다른 글
bank app - 입금 처리 (0) | 2023.04.19 |
---|---|
bank app - 계좌 목록 보기 (0) | 2023.04.19 |
bank app - 계좌 생성하기 (0) | 2023.04.19 |
bank app - 로그인 처리 (0) | 2023.04.19 |
bank app - 회원가입(트랜잭션처리) (0) | 2023.04.19 |