3. ToyProject Entity 생성

Miz·2021년 5월 11일
0

board-toy-project

목록 보기
3/6

https://github.com/mizm/board-toy
위의 레포지토리에 저장해두었습니다.

Spring 토이프로젝트 Entity 생성

JPA Auditing Configuration

  • jpa auditing을 위해 Jpaconfig 파일 생성
  • BoardApplication에 어노테이션을 붙여도 되지만, 추후 테스트 때 entity를 로딩하는 테스트가 아닌경우 (ex : @WebMvcTest) 등의 경우에서 테스팅에 문제가 생김

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

import java.util.Optional;
import java.util.UUID;

@EnableJpaAuditing
@Configuration
public class JpaConfig {

    @Bean
	public AuditorAware<String> auditorProvider() {
		//security를 통해 유저아이디를 꺼내오자.
		return () -> Optional.of(UUID.randomUUID().toString());
	}
}
  • @EnableJpaAuditing 을 통해 jpa Auditing을 쓴다고 스프링에 알려줌
  • SpringSecurity 적용 전에는 UUID로 생성자와 수정자를 정해주자.

BaseTimeEntity 생성

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;

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


    @CreatedDate
    @Column(updatable = false, name = "created_date")
    private LocalDateTime createdDate;

    @LastModifiedDate
    @Column(name = "modified_date")
    private LocalDateTime modifiedDate;

}
  • BaseTimeEntity를 생성한 이유
    - craetedDate, modifiedDate 만 사용하는 User 테이블을 만족시키기 위해 생성
    - 상속 구조를 통해 BaseEntity까지 생성

BaseEntity 생성

import lombok.Getter;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;

@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
public class BaseEntity extends BaseTimeEntity {

    @CreatedBy
    @Column(updatable = false, name = "created_by")
    private String createdBy;

    @LastModifiedBy
    @Column(name = "updated_by")
    private String updatedBy;
}
  • BaseTimeEntity를 상속함
  • 결국 BaseEntity를 다른 엔티티가 상속하면 createdBy, updatedBy, createdTime, updatedTime을 가질 수 있게 구성함.
  • JPA Auditing 을 통해 구현

그외 entity 구현

  • 간단한 기능을 포함한 Entity로 구현
  • 답글 , 댓글의 댓글 등은 추후 구현
  • 기본적으로 @Builder를 통해 빌더 패턴 구현

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User extends BaseTimeEntity{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Long id;

    @Column(length = 50)
    private String username;

    private String password;

    private String email;
	    
	@Builder
    public User(String username, String password, String email) {
        Assert.hasText(username, "username is Not null");
        Assert.hasText(password, "password is Not null");
        Assert.hasText(email, "email is Not null");

        this.username = username;
        this.password = password;
        this.email = email;
    }

}


@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Board extends BaseEntity{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "board_id")
    private Long id;

    private String title;

    @Column(columnDefinition = "TEXT")
    private String content;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;

	    @Builder
    public Board(String title, String content, User user) {
        Assert.hasText(title, "title is not null");
        Assert.hasText(content, "content is not null");
        Assert.notNull(user, "user is not null");
        this.title = title;
        this.content = content;
        this.user = user;
    }
}

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Comment extends BaseEntity{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "comment_id")
    private Long id;

    @Column(length = 500)
    private String content;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "board_id")
    private Board board;

	    @Builder
    public Comment(String content, User user, Board board) {
        Assert.hasText(content, "title is not null");
        Assert.notNull(user, "user is not null");
        Assert.notNull(board, "board is not null");
        this.content = content;
        this.user = user;
        this.board = board;
    }

}

  • @NoArgsConstructor(access = AccessLevel.PROTECTED) -> Spring 에서 Proxy를 만들때 아무것도 없는 생성자가 필요함
    - 혹시라도 모르니 access를 protected로 지정한다.
    - ex) User 클래스 기준으로 아래의 코드가 Lombok을 통해 생성 된다.

    	```java
    	protected User() {
    
    	}
    	```
  • 모든 ManyToOne 관계는 fetchType을 Lazy로딩으로 지정해준다
    - N+1 문제 해결을 위해

  • 기본적인 연관관계매핑은 FK가 들어가는 Entity에만 지정 해둔뒤 추후 필요에 따라 구현

기본 JPA Repository 구현

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import spring.board.entity.User;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}



import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import spring.board.entity.Board;

@Repository
public interface BoardRepository extends JpaRepository<Board, Long> {
}



import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import spring.board.entity.Comment;

@Repository
public interface CommentRepository extends JpaRepository<Comment, Long> {
}

  • 추후 쿼리가 필요하면 interface 등록 or QueryDsl으로 적용할 예정.
profile
2년차 백엔드 개발자

0개의 댓글