와이유스토리

[도트타이머] 4. JPA 폴더링 및 간단한 회원가입 구현(보안X) 본문

프로젝트/백엔드

[도트타이머] 4. JPA 폴더링 및 간단한 회원가입 구현(보안X)

유(YOO) 2022. 12. 14. 23:47

JPA

폴더링을 어떻게 할 것인가가 고민이다.

프로그래머스에서 봤을 때는 user, product, review 등 테이블 속성별로 나누던데, 다른 분들을 보니 controller, service, repository(dao) 등 기능별로 나누기도 하는 것 같다.

이번 프로젝트는 스프링부트의 기능과 구조를 알아보는 것이니 후자로 하기로 한다.

여기서 또 dto, domain, vo, mapper 등은 어떻게 할 것인가...하는 고민이 생겼지만 폴더를 각각 생성하기로 했다

 

User.class

가장 먼저 Domain(Entity)를 DB 설계한대로 만들었다.

package com.dotetimer.domain;

import jakarta.persistence.*; // javax에서 바뀜
import jakarta.validation.constraints.NotNull;
import lombok.*;
import org.hibernate.annotations.ColumnDefault;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.ArrayList;
import java.util.List;
import java.util.Collection;
import java.util.stream.Collectors;

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User implements UserDetails {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 전략 종류 Identity, Sequence, Table
    @Column(name = "id") // 테이블 Key
    private int id;

    @Column(unique = true)
    @NotNull
    private String email;

    @Column(length = 300)
    @NotNull
    private String password;

    private String name;

    private String introduction;

    @ColumnDefault("false")
    private boolean opened;

    @Column(name = "user_img")
    private String profileImage;

    @ColumnDefault("false")
    private boolean premium;

    @ColumnDefault("0")
    private int coinCount;

    @Setter
    private String refreshToken;
}

UserSignReqDto.class

회원가입이나 로그인을 요청할 때, 사용자는 이메일과 비밀번호를 입력하므로 이에 대한 틀을 작성했다.

package com.dotetimer.dto;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@NotNull
public class UserSignReqDto {
    @Email
    private String email;
    private String password;
}

UserController.class

http://localhost:8080/api/user/sign_up 주소로 사용자의 Post 요청을 받는 컨트롤러다.

package com.dotetimer.controller;

import com.dotetimer.dto.UserSignReqDto;
import com.dotetimer.service.UserService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
@RequestMapping(value = "api/user")
public class UserController {
    private final UserService userService;

    @PostMapping(path = "/sign_up")
    public ResponseEntity<?> signUp(@Valid @RequestBody UserSignReqDto userSignReqDto) {
        //log.info("Request : sign_up");
        userService.signUp(userSignReqDto);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }
}

UserRepository.class

DAO 작성

package com.dotetimer.repository;

import com.dotetimer.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Integer> {
    Optional<User> findByEmail(String email);
}

UserService.class

Service 계층이다. name을 어떻게 할까하다가 이메일에서 도메인을 제외하고 저장하기로 했다.

Not Null이기 때문에 null 확인을 생략하고 중복 확인 후 DB에 저장한다.

package com.dotetimer.service;

import com.dotetimer.domain.User;
import com.dotetimer.dto.UserSignReqDto;
import com.dotetimer.repository.UserRepository;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
@Transactional
public class UserService {
    private final UserRepository userRepository;
    
    public User signUp(UserSignReqDto userSignReqDto) {
    	checkDuplicateUser(email);
        User user = userRepository.save(
                User.builder()
                        .email(userSignReqDto.getEmail())
                        .password(userSignReqDto.getPassword())
                        .name(userSignReqDto.getEmail().split("@")[0])
                        .build());
        return user;
    }

    private void checkDuplicateUser(String email) {
        userRepository.findByEmail(email)
                .ifPresent(param -> {
                    throw new DuplicateKeyException("email = " + email);
                });
    }
}

 

Comments