본문 바로가기

SPRING/Spring

[스프링| 스프링 입문 | 코드로 배우는 스프링] 회원 웹 기능 - 등록, DTO와 DAO

// 회원 가입을 처리하는 메서드입니다.
public Long join(Member member) {

    // 중복 회원이 있는지 검증하는 private 메서드를 호출합니다.
    validateDuplicateMember(member); //중복 회원 검증
    
    // 리포지토리의 save 메서드를 사용하여 회원 정보를 저장합니다.
    memberRepository.save(member);
    
    // 저장된 회원의 ID를 반환합니다. 저장 후에는 ID가 할당됩니다.
    return member.getId();
}

// 중복 회원을 검증하는 메서드입니다. 이 메서드는 private으로 선언되어,
// 클래스 내부에서만 사용할 수 있습니다.
private void validateDuplicateMember(Member member) {
    
    // memberRepository를 사용하여 이름으로 회원을 찾습니다.
    // 결과는 Optional 객체로 반환됩니다.
    memberRepository.findByName(member.getName())
            // Optional 객체의 ifPresent 메서드를 사용하여 결과가 존재할 경우,
            // 즉, 이름이 같은 회원이 이미 존재할 경우 예외를 던집니다.
            .ifPresent(m -> {
                throw new IllegalStateException("이미 존재하는 회원입니다.");
            });
}​
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>

<div class="container">
    <!-- 'action' 속성으로 지정된 URL로 데이터를 전송하는 POST 방식의 폼 -->
    <form action="/members/new" method="post">
        
        <!-- 입력 그룹을 묶어주는 div, 스타일링과 구조화에 도움을 줌 -->
        <div class="form-group">
        
            <!-- 'for' 속성이 'name'인 label 요소, 사용자가 이해하기 쉽게 필드에 이름을 제공 -->
            <label for="name">이름</label>
            
            <!-- 'id'와 'name' 속성을 가진 입력 필드, 사용자로부터 이름을 입력받음 -->
            <!-- 'placeholder'는 입력 필드에 예시 텍스트를 표시함 -->
            <input type="text" id="name" name="name" placeholder="이름을 입력하세요!">
            
        </div>
       
        <!-- 폼을 제출하는 버튼, 클릭하면 폼 데이터가 서버로 전송됨 -->
        <button type="submit">등록</button>
        
    </form>
</div> <!-- /container -->

</body>
</html>
package hello.hellospring.controller; // 패키지 선언, 이 클래스가 hello.hellospring.controller 패키지에 속한다는 것을 나타냅니다.

// MemberForm 클래스 선언, 보통 사용자 입력을 받기 위한 폼의 데이터를 담는 객체를 표현합니다.
public class MemberForm {

    private String name; // private 접근 제어자를 가진 String 타입의 멤버 변수 name 선언, 클래스 외부에서 직접 접근할 수 없도록 합니다.

    // name 변수의 값을 반환하는 public getter 메서드, 외부에서 name 값을 조회할 수 있도록 합니다.
    public String getName() {
        return name; // 현재 인스턴스의 name 값을 반환합니다.
    }

    // name 변수에 값을 설정하는 public setter 메서드, 외부에서 name 값을 설정할 수 있도록 합니다.
    public void setName(String name) {
        this.name = name; // 메서드로 전달된 인자를 현재 인스턴스의 name 변수에 할당합니다.
    }
}
// @PostMapping 애노테이션은 이 메서드가 HTTP POST 요청을 처리하며, 
// 'members/new' 경로로 들어오는 요청을 매핑합니다.
@PostMapping("members/new")
public String create(MemberForm form) { // 'create' 메서드는 MemberForm 객체를 파라미터로 받습니다.
                                        // 폼 데이터가 이 객체에 바인딩됩니다.

    Member member = new Member(); // Member 도메인 객체를 생성합니다.
    member.setName(form.getName()); // MemberForm에서 받은 이름을 Member 객체에 설정합니다.

    memberService.join(member); // MemberService를 사용하여 회원가입 로직을 수행합니다.
                                // 이는 일반적으로 저장소에 Member 객체를 저장하는 것을 포함합니다.

    return "redirect:/"; // 회원가입 처리가 끝난 후, 사용자를 사이트의 홈 페이지로 리다이렉트합니다.
}

DTO(Data Transfer Object)와 DAO(Data Access Object)는 데이터 처리와 관련된 두 가지 다른 디자인 패턴입니다.

  1. DTO (Data Transfer Object)
    • 목적: DTO는 계층 간 데이터 교환을 위해 사용됩니다. 주로 네트워크를 통해 다른 시스템이나 계층으로 데이터를 전송할 때 사용하는 객체입니다.
    • 특징: 이는 일반적으로 로직을 포함하지 않는, 순수한 데이터 객체입니다. 데이터와 그 데이터에 접근하기 위한 getter/setter 메소드만 포함할 수 있습니다.
    • 사용 예: 웹 클라이언트로부터 받은 폼 데이터를 서버에 전달할 때, 서버에서 클라이언트로 데이터를 보낼 때 등에서 사용됩니다.
  2. DAO (Data Access Object)
    • 목적: DAO는 데이터베이스나 다른 영속성 메커니즘에 접근하기 위한 객체입니다. 이 패턴은 데이터베이스 쿼리를 추상화하고, 데이터베이스 연산을 캡슐화하는 데 사용됩니다.
    • 특징: DAO는 데이터베이스의 CRUD(Create, Read, Update, Delete) 연산을 위한 메서드를 정의합니다. 이를 통해 비즈니스 로직과 데이터베이스 사이의 분리를 촉진합니다.
    • 사용 예: 데이터베이스에서 사용자 정보를 조회하거나 업데이트할 때 DAO 메서드를 사용합니다.

간단히 말해서, DTO는 단지 데이터를 전달하는 역할을 하며, DAO는 데이터를 조작하는 로직과 접근 방법을 정의합니다. DTO는 여러 데이터를 묶어서 전송하는 컨테이너 역할을 하고, DAO는 데이터베이스와의 통신을 관리합니다.