스파르타 강의/스프링 강의

스프링 JWT 구현-3

SHsus 2022. 12. 4. 18:45

이번에는 Entity 부분이다. 쉽게 말해 실체, 객체 라고 생각하면 되는 부분이다.

데이터의 집합을 의미하며, 저장되고 관리되어야 하는 부분이다.

 

 

 

 

 

 

 

 

Product

상품들의 정보를 다루는 부분의 엔티티 이다.

package com.sparta.myselectshop.entity;

import com.sparta.myselectshop.dto.ProductMypriceRequestDto;
import com.sparta.myselectshop.dto.ProductRequestDto;
import com.sparta.myselectshop.naver.dto.ItemDto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;

@Getter
@Setter
@Entity
@NoArgsConstructor
public class Product extends Timestamped {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id;

    @Column(nullable = false)
    private String title;

    @Column(nullable = false)
    private String image;

    @Column(nullable = false)
    private String link;

    @Column(nullable = false)
    private int lprice;

    @Column(nullable = false)
    private int myprice;

    @Column(nullable = false)
    private Long userId;

    public Product(ProductRequestDto requestDto, Long userId) {
        this.title = requestDto.getTitle();
        this.image = requestDto.getImage();
        this.link = requestDto.getLink();
        this.lprice = requestDto.getLprice();
        this.myprice = 0;
        this.userId = userId;
    }

    public void update(ProductMypriceRequestDto requestDto) {
        this.myprice = requestDto.getMyprice();
    }

    public void updateByItemDto(ItemDto itemDto) {
        this.lprice = itemDto.getLprice();
    }

}

 

@Entity

JPA 에서 엔티티는 테이블에 대응하는 하나의 클래스이다.
이게 붙은 클래스는 JPA 가 관리해주며, JPA 를 사용해서 DB 테이블과 매핑할 클래스는 꼭 사용해야 한다.

 

@Id

JPA 가 객체를 관리할 때 식별할 기본키를 지정한다.
@GeneratedValue 기본키 생성을 DB 에 위임하는 방식으로 id 값을 따로 할당하지 않아도
DB 가 자동으로 AUTO_INCREMENT 를 하여 기본키를 생성해준다.
strategy = GenerationType.IDENTITY 이 부분은 다른 옵션이 또 있다 그 부분은 쓸 때 검색해보자.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // ID 가 자동으로 생성 및 증가
private Long id;

 

@Column

객체 필드를 테이블의 칼럼(열) 에 매핑시켜주는 역할을 한다.

 

 

 

 

 

 

 

User

유저의 정보를 다루게 될 엔티티이다.

package com.sparta.myselectshop.entity;

import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Getter
@NoArgsConstructor
@Entity(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    // nullable : null 허용 여부
    // unique   : 중복 허용 여부 (false 일때 중복 허용)
    @Column(nullable = false, unique = true)
    private String username;

    @Column(nullable = false)
    private String password;

    @Column(nullable = false, unique = true)
    private String email;

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

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

}

 

@Entity(name = "users")

위에서 나온 엔티티 어노테이션 과는 다르게 속성도 추가로 사용한 경우다.
위의 코드처럼 @Table 이 없고 @Entity 만 존재하면 name 속성에 의해 엔티티와 Table 이름 을 결정

 

@Enumerated(value = EnumType.STRING)

엔티티 클래스 속성중 Enum 타입의 변수에서 사용한다.
선언된 상수의 이름을 String 클래스 타입으로 변환하여 DB 에 넣어준다.
@Column(nullable = false)
@Enumerated(value = EnumType.STRING)
private UserRoleEnum role;​

위같은 경우에는 Column 에 저장하는 형태가 된다.

 

 

 

 

 

 

 

 

UserRoleEnum


package com.sparta.myselectshop.entity;

public enum UserRoleEnum {

    USER,  // 사용자 권한
    ADMIN  // 관리자 권한
}

 

Enum

Enum 클래스 형을 기반으로 한 열거형 클래스 선언
Enum 그 자체가 가지는 의미는 "관련이 있는 상수들의 집합" 을 의미한다.
클래스처럼 보이게 하는 상수이다.
서로 관련있는 상수들끼리 모아 상수들을 대표할 수 있는 이름으로 타입을 정의하는 것

 

말로하면 너무 어려워서 몇가지 특징만을 숙지하자

  • 열거형으로 선언된 순서에 따라 0부터 index 값을 가진다.(순차적으로 증가)
  • 여기서 지정된 상수들은 모두 대문자로 선언하고 마지막에 세미콜론(;) 을 사용하지 않는다.
  • 상수와 특정 값을 연결시킬 경우에만 마지막에 세미콜론을 붙여준다.

 

참고 링크

 

[JAVA] 자바_enum 클래스 (열거형_enumeration type)

- enum 클래스란? - enum 클래스는 열거체(enumeration type)으로 JDK 1.5 이상의 버전에서만 사용이 가능하다. 간단하게 정의하자면 다음과 같다. - 클래스처럼 보이게 하는 상수 - 서로 관련있는 상수들끼

mine-it-record.tistory.com

 

 

 

 

 

 

 

 

Timestamped

상품을 담거나 하는 변동사항이 생길 경우에 자동으로 그 시점의 날짜및 시간정보가 들어가는 부분
package com.sparta.myselectshop.entity;

import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.LocalDateTime;

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class Timestamped {

    @CreatedDate		// 데이터를 저장할 때 생성된 시간 정보 자동 저장
    @Column(updatable = false)
    private LocalDateTime createdAt;

    @LastModifiedDate		// 데이터를 저장할 때 수정된 시간 정보 자동 저장
    @Column
    private LocalDateTime modifiedAt;
}

 

@MappedSuperclass

객체의 입장에서 공통 매핑 정보가 필요할 때 사용된다.
id, name 은 객체의 입장에서 볼 때 계속 나온다. 이렇게 공통 매핑 정보가 필요할 때,
부모 클래스에 선언하고 속성만 상속 받아서 사용하고 싶을 때 사용한다.
그래서 위의 Product 부분에 extends 로 Timestamped 를 상속받게 되어있다.

 

@EntityListeners(AuditingEntityListener.class)

엔티티의 변화를 감지하고 테이블의 데이터를 조작하는 일을 한다.
해당 클레스에 Auditing(감사) 기능을 포함한다.

 

@LastModifiedDate @CreatedDate

위의 어노테이션에 대한 추가적인 설명
날짜가 자동으로 올라가야하는데 null 올라가면서 않올라가는 증상이 있었다.
이는 실행부인 어플리케이션에 @EnableJpaAuditing 가 존재해야만 작동을 하는것을 알게 되었다.
@EnableJpaAuditing 이 어노테이션이 존재해야만 JPA Auditing 기능이 활성화가 된다.

 

 

다음에는 매우 중요한 부분중의 하나인 JwtUtil 을 살펴보도록 하자.