🔙뒤로가기

회원 목록 컨트롤러 추가

MemberController에 list 매핑 추가

@GetMapping("/member")
    public String list(Model model){
        List<Member> members = memberService.findMembers();
        model.addAttribute("members", members);
        return "members/memberList";
    }

인텔리제이의 Ctrl+Alt+N 단축키를 사용하면 아래와 같이 압축할 수 있다.

@GetMapping("/member")
    public String list(Model model){
        model.addAttribute("members", memberService.findMembers());
        return "members/memberList";
    }

회원 목록 뷰(templates/members/memberList.html

<!DOCTYPE HTML>
<html xmlns:th="<http://www.thymeleaf.org>">
<head th:replace="fragments/header :: header"/>
<body>
<div class="container">
    <div th:replace="fragments/bodyHeader :: bodyHeader"/>
    <div>
        <table class="table table-striped">
            <thead>
            <tr>
                <th>#</th>
                <th>이름</th>
                <th>도시</th>
                <th>주소</th>
                <th>우편번호</th>
            </tr>
            </thead>
            <tbody>
            <tr th:each="member : ${members}">
                <td th:text="${member.id}"></td>
                <td th:text="${member.name}"></td>
                <td th:text="${member.address?.city}"></td>
                <td th:text="${member.address?.street}"></td>
                <td th:text="${member.address?.zipcode}"></td>
<!--address?.city 처럼 ?를 사용하면 null을 무시한다 -->
            </tr>
            </tbody>
        </table>
    </div>
    <div th:replace="fragments/footer :: footer"/>
</div> <!-- /container -->
</body>
</html>

타임리프에서 ?를 사용하면 null을 무시한다.

<aside> ⚠️ 참고: 폼 객체 사용 vs 엔티티의 직접 사용

단순한 요구사항의 경우, 폼 객체(MemberForm) 대신 엔티티(Member)를 직접 사용하여 등록 및 수정 화면을 구현할 수 있다. 그러나 화면 요구사항이 점점 복잡해지면 엔티티에 화면 처리를 위한 기능이 증가하게 되어 엔티티가 화면에 종속되어 변하게 된다. 이로 인해 엔티티가 지저분해지고 유지보수가 어려워진다.

실무에서 엔티티는 핵심 비즈니스 로직에만 집중해야 한다. 화면 처리나 API 관련 로직은 폼 객체나 DTO(Data Transfer Object)를 별도로 생성하여 사용하는 것이 좋다. 이렇게 구현하면 화면이나 API 요구사항에 따라 폼 객체나 DTO를 사용하여 처리할 수 있고, 엔티티를 최대한 순수한 상태로 유지할 수 있다.

</aside>