17. 계좌 목록 만들기(1단계)

1. 사전 기반 지식

CREATE TABLE 학생 (
    학생ID INT PRIMARY KEY,
    이름 VARCHAR(100)
);

CREATE TABLE 강좌 (
    강좌ID INT PRIMARY KEY,
    강좌명 VARCHAR(100)
);

CREATE TABLE 수강 (
    학생ID INT,
    강좌ID INT,
    PRIMARY KEY (학생ID, 강좌ID),
    FOREIGN KEY (학생ID) REFERENCES 학생(학생ID),
    FOREIGN KEY (강좌ID) REFERENCES 강좌(강좌ID)
);

만약 N:N 관계, 한 학생이 여러 개의 강좌를 수강할 수 있고, 한 강좌가 여러 학생에 의해 수강될 수 있는 경우 데이터베이스에 모델링하는 것은 불가능하기 때문에, 일반적으로 중간 테이블(또는 연결 테이블, 조인 테이블이라고도 함)을 사용하여 N:N 관계를 두 개의 1:N(일대다) 관계로 분리한다.

2. AccountRepository, account.xml 코드 확인하기

AccountRepository
// interface 파라미터명과 xml에 사용할 변수명을 다르게 사용해야 된다면 @param 어노테이션을
// 사용할 수 있다. 그리고 2개 이상의 파라미터를 사용할 경우 반드시 @param 어노테이션을 사용하자!
public List<Account> findByUserId(@Param("userId") Integer principalId);
account.xml
<select id="findByUserId" resultType="com.tenco.bank.repository.model.Account">
    select * from account_tb where user_id = #{userId} 
</select>

3. 계좌 목록 기능 만들기

list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- header.jsp -->
<%@ include file="/WEB-INF/view/layout/header.jsp"%>

<!-- start of context.jsp(xxx.jsp) -->
<div class="col-sm-8">
	<h2>계좌목록(인증)</h2>
	<h5>Bank App에 오신걸 환영합니다.</h5>

	<c:choose>
		<c:when test="${accountList != null}">
			<%-- 계좌 존재 : html 주석을 사용하면 오류 발생 (jstl 태그 안에서) --%>
			<table class="table">
				<thead>
					<tr>
						<th>계좌 번호</th>
						<th>잔액</th>
					</tr>
				</thead>
				<tbody>
					<c:forEach var="account" items="${accountList}">
						<tr>
							<td>${account.number}</td>
							<td>${account.balance}</td>
						</tr>
					</c:forEach>
				</tbody>
			</table>
		</c:when>
		<c:otherwise></c:otherwise>
	</c:choose>
	<!-- 계좌가 없는 경우 있는 경우를 분리 -->
	<!-- 계좌가 있는 사용자 일 경우 반복문을 활용할 예정 -->

</div>
<!-- end of col-sm-8 -->
</div>
</div>
<!-- end of context.jsp(xxx.jsp) -->

<!-- footer.jsp -->
<%@ include file="/WEB-INF/view/layout/footer.jsp"%>
AccountController
/**
 * 계좌 목록 화면 요청 
 * 주소설계 : http://localhost:8080/account/list, ..../ 
 * @return list.jsp 
 */
@GetMapping({"/list", "/"})
public String listPage(Model model) {

    // 1. 인증검사 
    User principal = (User)session.getAttribute("principal");
    if(principal == null) {
        throw new UnAuthorizedException("인증된 사용자가 아닙니다.", HttpStatus.UNAUTHORIZED);
    }
    // 2. 유효성 검사 
    // 3. 서비스 호출 
    List<Account> accountList = accountService.readAccountListByUserId(principal.getId());
    if(accountList.isEmpty()) {
        model.addAttribute("accountList", null);
    } else {
        model.addAttribute("accountList", accountList);
    }

    // JSP 데이트를 넣어 주는 방법 
    return "account/list";
}
accountService
public List<Account> readAccountListByUserId(Integer principalId) {
    List<Account> accountListEntity = null; // null ??? --> isEmpty()로 받으려면 최소한 객체는 있어야되는거아닌가? 
    try {
        accountListEntity = accountRepository.findByUserId(principalId);
    } catch (DataAccessException e) {
        throw new DataDeliveryException("잘못된 처리 입니다.", HttpStatus.INTERNAL_SERVER_ERROR);
    } catch (Exception e) {
        throw new RedirectException("알 수 없는 오류", HttpStatus.SERVICE_UNAVAILABLE);
    }
    return accountListEntity;
}