Spring MVC 패턴으로 구현한 회원가입/로그인 + 어노테이션 정리 -① 프로젝트 생성과 Model

Jee hyun. k·2021년 7월 13일
12
post-thumbnail

이번 포스팅에서는 MVC 패턴으로 구현한 회원가입/ 로그인 기능을 다루고 각각의 메소드에 사용된 어노테이션을 정리해 볼 것이다.

우선 전체적인 구조는 다음과 같다.

  • DTO 는 데이터를 가지고 다닐 패키지 녀석이라서 모든 통신 사이에서 작용한다.
  • Controller : 클라이언트와의 요청과 응답을 담당하는 부분이며 서비스에서 데이터를 주고 받는다.
  • Service : 비즈니스 로직을 담당하는 부분이다.
    이게 무슨말일까? 서버에서 일어나는 모든 처리들을 클라이언트가 알아먹을 수 있게(?) 사용자의 요구사항을 처리하는 일을 한다고 보면 된다.
  • Repository : JPA를 사용했을 때 DB에서 쿼리문(SQL문)의 역할을 한다.
    POST, GET, DELETE 시 어떤 값을 기준으로 해당 명령을 처리할 것인지를 기재하였다.
  • Entity : DB의 테이블 역할을 담당한다.

JPA (JAVA Persistence API)

  • JPA는 애플리케이션과 JDBC 사이에서 동작.
    개발자가 JPA를 사용하면, JPA 내부에서 JDBC API를 사용하여 SQL을 호출,
    DB와 통신한다.

즉, 개발자가 직접 JDBC API를 쓰는 것이 아님

JPA를 왜 사용해야 하는지!

  1. 개발 - SQL 중심적인 개발의 문제점
    → SQL 중심적인 개발에서 객체 중심으로
  2. 생산성 JPA를 사용하는 것은 마치 Java Collection에 데이터를 넣었다 빼는 것처럼 사용할 수 있게 만든 것이다.

특히, 수정이 굉장히 간단하다.
객체를 변경하면 그냥 알아서 DB에 UPDATE Query가 나간다.

  1. 유지보수가 용이
    기존 방식 : 필드 변경 시 모든 SQL을 수정해야 한다.
    JPA: 필드만 추가하면 된다. SQL은 JPA가 처리하기 때문에 손댈 것이 없다.
결론: JPA 쵝오..^^ 외않써!

프로젝트 생성

먼저 새롭게 spring 프로젝트를 생성해준다.
이 글에서는 IntelliJ IDE을 사용하여

  1. new → project → spring Initializr 로 생성해주었으며
  • JAVA 8 ver
  • SDK 1.8 ver
  • gradle / jar
    으로 프로젝트를 환경을 구축하였다.
    (https://start.spring.io/ 를 통해 생성해도 좋다.)

추가할 dependencies

  • Web (build)
  • JPA
  • h2
  • MySQL
  • Lombok
  • (+thymleaf) 클라이언트를 완성해줄 템플릿 엔진

2 . src → main → java → (프로젝트명의) package
안에 mvc 패턴을 구성할 패키지를 생성해준다.
패키지와 클래스, 인터페이스 구성은 다음과 같다.

📁 controller

  • UserController
  • HomeController

📁 model ←이번에 정리 할 부분

  • User

  • UserRole

📁 service

  • UserService

📁 repository

  • [Interface] UserRepository

📁 dto

  • SignupRequestDto

📁 security

  • WebSecurityConfig
    📁kakao
    UserDetailsImpl
    UserDetailsServiceImpl

📁 exception

  • ApiException

Model

  Model 패키지는 위의 맵에서 알 수 있듯 Entity. DB의 테이블 을 담당하는 부분의 패키지로 지정했다. MVC 패턴에서 'domain'이라는 패키지 명으로 많이 작업한다.

첫번째로 'User' 테이블을 생성해야하기 때문에 User 클래스를 생성한다.
SQL문으로 치면 create table user(...); 에 해당하는 작업이다.

  • User Class

    * 만약 annotation이 활성화 되지 않는다면 Alt+Enter 를 눌러 import를 추가해줍니다.

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;  
  
  
@Setter
@Getter // get 함수를 일괄적으로 만들어줍니다.
@NoArgsConstructor // 기본 생성자를 만들어줍니다.
@Entity // DB 테이블 역할을 합니다.
public class User  {



    public User(String username, String password, String email, UserRole role) {
        this.username = username;
        this.password = password;
        this.email = email;
        this.role = role;
        this.kakaoId = null;
    }

    public User(String username, String password, String email, UserRole role, Long kakaoId) {
        this.username = username;
        this.password = password;
        this.email = email;
        this.role = role;
        this.kakaoId = kakaoId;
    }


    // ID가 자동으로 생성 및 증가합니다.
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Id
    private Long id;

    // 반드시 값을 가지도록 합니다.
    @Column(nullable = false)
    private String username;

    @Column(nullable = false)
    private String password;

    @Column(nullable = false)
    private String email;

    @Column(nullable = false)
    @Enumerated(value = EnumType.STRING)
    private UserRole role;

    @Column(nullable = true)
    private Long kakaoId;
}

1. @Getter : 모든 컬럼의 getter 함수를 일괄적으로 만들어준다.
예를 들어 여기서는 getUsername , getPassword와 같은 getter 메소드를 모두 생성해주어야 하지만 @Getter annotation을 추가하면 이것이 일괄적으로 getter를 생성해주는 역할을 한다.

2. @Setter : 마찬가지로 Setter 함수를 일괄적으로 생성해주는 annotation 이다.

두가지 모두 따로 Getter와 Setter 메소드를 만들지 않아도 자바 내장 객체로 생성해주는 기능을 한다.

  ※ 여기서 잠깐! Getter와 Setter가 뭔지 모르겠다면?

우선 객체지향 프로그래밍에 대해 자세히 공부하는것을 추천. 이전 포스팅을 참고하길 바란다.
https://velog.io/@jee1818/%EC%9E%90%EB%B0%94-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%98-Getter-%EC%99%80-Setter

3. @NoArgsConstructor : 따로 생성자를 생성해주지 않아도 기본 생성자 자동 생성.

* 생성자 어노테이션 종류

@NoArgsConstructor : 파라미터가 없는 기본 생성자 생성
@AllArgsConstructor : 모든 필드 값을 파라미터로 받는 생성자 생성
@RequiredArgsConstructor : final이나 @NonNull (null을 허용하지 않음) 인 필드 값만 파라미터로 받는 생성자를 생성
  • @Getter, @Setter, @NoArgsConstructor, 모두 위의 import 된 것을 보면 알 수 있듯 Lombok의 annotion 기능이다.

4. @Entity : 테이블 역할을 해주는 클래스임을 지정

5. @GeneratedValue / @Id :

  • @Id는 해당 프로퍼티가 테이블의 primary key 역할이라는 것을 지정

  • @GeneratedValue 은 primary key 값이 자동으로 1씩 증가되도록 만들어 준다.

    여기서 (strategy = GenerationType. AUTO ) 라고 지정한 것을 살펴보자면,
    우선 GenerationType은 두가지 선택적 속성이 있다.


  • generator : @SequenceGenerator @TableGenerator annotaion 에서 명시된 primary key 생성자를 재사용할 때 쓰인다.
    (디폴트 값은 공백문자(""))

  • strategy : persistence provider가 Entity의 primary key 를 생성할 때 사용해야 하는 생성 전략을 의미한다.
    (디폴트 값은 AUTO)

    • AUTO : (persistence provider가) 특정 DB에 맞게 자동 선택
    • IDENTITY : DB의 identity 컬럼을 이용
    • SEQUENCE : DB의 시퀀스 컬럼을 이용
    • TABLE : 유일성이 보장된 데이터베이스 테이블을 이용

6. @Column (nullable = false) : .디폴트 값은 true이며 false로 설정 시 해당 컬럼의 nullable 제약 조건이 NOT NULL 이 된다.

  @NotNULL annotation과의 차이

  • @NotNULL 은 유효성 검사를 해준다
  • (nullable = false) 은 유효성 검사를 해주지 않고 데이터 베이스에 명시적으로 제약조건을 걸어주기만 한다.

  • UserRole Class

  public enum UserRole {
    USER,  // 사용자 권한
    ADMIN  // 관리자 권한
}
  • user의 권한을 부여해주는 클래스이다.

    자 그런데 이 enum 타입은 뭘까?

enum 키워드는 열거 타입을 선언하기 위한 키워드이다. 보통 몇가지 한정된 데이터들을 가지는 경우에 이 열거형을 사용한다.





Enum Class

  흔히 상수를 정의할 때 우리는 String , int 와 같은 방식으로 정의해왔다.
그런데 해당 상수들이 만약 '연관성' 을 가질 경우 이 연관성을 부여할 수 있는 방법이 따로 없을까? 그래서 나온 것이 이 열거형 enum 클래스이다.
즉, 서로 연관된 상수들의 집합 을 의미 하는 class가 이 enum 클래스이다. java 1.5 버전부터 새롭게 추가되었다.

enum 클래스를 사용하는 방법은

  1. 클래스 내부에 선언하는 방법
  2. 별도의 .java 파일 선언으로 하는 방법

두가지 방법이 있는데, 해당 메소드에서는 두번째 방법인 열거 타입 이름으로 소스파일(.java)을 생성하여 지정해주었다.

 * enum 클래스를 사용할 경우의 이점은 다음과 같다.

  1. 가독성 up

  2. 인스턴스 생성과 상속을 방지, 상수값의 타입 안정성이 보장됨

  3. enum class를 사용해 새로운 상수들의 타입을 정의함으로 정의한 타입이외의 타입을 가진 데이터값을 컴파일시 확인 가능.



  이렇게 회원/로그인 기능의 DB를 생성과 관리를 담당하는 model 패키지의 User 클래스와 UserRole 클래스, Enum 클래스란 무엇인지 정리해보았다.

다음 포스팅에서 이어서 Service,Dto, Security 등등 을 다루도록 하겠다.

profile
junior developer

0개의 댓글