(UMC) 7. JPA를 통한 엔티티 설계, 매핑 & 프로젝트 파일 구조 이해 (1)

jimmy·2024년 5월 23일
0

UMC 6기

목록 보기
7/11

패키지 종류

domain

JPA에서 사용하기 위한 엔티티 클래스 저장하기 위한 패키지

controller

http 요청이 오면, 그에 대한 응답을 주는 클래스들을 모아둔 패키지로,
응답을 주기 위한 과정들을 service에서 처리하도록 한다.

service

비즈니스 로직이 필요한 클래스들의 모임

controller -> service 호출
service -> repository 호출

repository

DB와 통신을 하는 계층

dto

클라이언트가 body에 담아서 보내는 데이터를 받기 위한 클래스
혹은 DB에서 받아온 데이터를 클라이언트에게 보여주기 위한 클래스

엔티티 자체를 그대로 응답으로 보내면 문제가 생긴다.
만약에, 요구사항 변경이 생겨서 엔티티 변경이 발생했을 시,
엔티티를 그대로 응답으로 주면 DB의 변경사항이 프론트 개발자에게까지 영향을 주게 된다.

converter

데이터 형식 간의 변환 수행하는 역할 (entity -> dto)
추가로 entity 생성 역시 converter에서 수행하기도 한다.

엔티티 생성을 service에서 하는 경우도 있다.
converter에서 엔티티 생성을 하게 되면, service는 순수하게 비즈니스 로직에만 집중할 수 있어서 단일 책임 원칙 측면에서 더 좋다!

converter 사용 위치

  1. service에서 dto 생성
    service에서 dto를 controller에게 리턴
  2. controller에서 dto 생성
    service에서 entity 리턴하고, controller에서 dto 만들어서 응답

1번의 장점은 controller에 엔티티가 노출되지 않아 보안적인 측면에 좋다는 것이다.
2번의 장점은 service의 함수가 범용성이 커져 유지보수가 편해진다.

무엇을 사용해야하는지에대한 정답은 없지만, 2번의 경우 서비스에서 엔티티를 반환할 수 없는 경우가 자주 생기므로 이 상황에서는 dto를 반환해야한다.

DB 준비

application.yml

spring:
  datasource: 
    url: jdbc:mysql://localhost:3306/study
    username: 유저 이름
    password: 비밀번호
    driver-class-name: com.mysql.cj.jdbc.Driver
  sql:
    init:
      mode: never
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL8Dialect
        show_sql: true
        format_sql: true
        use_sql_comments: true
        hbm2ddl:
          auto: update
        default_batch_fetch_size: 1000

Entity 매핑

@GeneratedValue(strategy = GenerationType.IDENTITY)

기본키 생성 방식을 JPA가 통신을 하는 DBMS의 방식을 따른다는 뜻이다. 즉, MySQL을 사용하면 MySQL을 따르게 되는 것이다.

빌더 패턴 사용

@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor

자바의 디자인 패턴 중 하나인 빌더 패턴을 사용하려면 위 세 개의 어노테이션을 사용해야한다.
빌더 패턴을 사용하면 생성자를 사용하는 것보다 더욱 편리하게 코딩이 가능하다.

@NoArgsConsructor로 기본 생성자의 생성을 방지하고, @Builder를 이용하여 객체 생성에 유연성을 더해주는 것이며, @Builder는 생성자 유무에 따라 다음과 같이 동작한다.

생성자가 없는 경우 : 모든 멤버 변수를 파라미터로 받는 기본 생성자 생성
생성자가 있을 경우 : 따로 생성자를 생성하지 않음

즉, @NoArgsConstuctor를 사용하여 기본 생성자가 존재하기 때문에, @AllArgsConstructor로 모든 변수를 파라미터로 받는 생성자를 생성할 수 있다.

📙출처

enums 패키지

enum은 도메인 아래에 enums 패키지 안에 작성해주겠다.

public enum Gender {
	MALE, FEMALE
}

그리고 이 enum을 사용하고자 하는 엔티티에는

@Enumerated(EnumType.STRING)
    private Gender gender;

이런식으로 작성해주면 된다.
이때, EnumType을 반드시 STRING으로 해줘야하는데, 그 이유는 기본 값은 ORDINAL을 사용하면 DB에 enum의 순서가 저장이 된다. 만약 enum의 순서가 바뀌게 되면 에러가 생기기 때문이다.

Created_at, Updated_at

거의 모든 엔티티에서 사용하기 때문에 따로 빼서 작성해줄것이다.

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

    @CreatedDate
    private LocalDateTime createdAt;

    @LastModifiedDate
    private LocalDateTime updatedAt;
}

그리고 사용하고자 하는 엔티티 클래스에 위의 클래스를 상속 받으면 된다.(extends)

Spring boot Application 자체에도 JpaAuditing 사용이 가능하도록 변경을 해줘야한다.

@SpringBootApplication
@EnableJpaAuditing
public class StudyApplication {

	public static void main(String[] args) {
		SpringApplication.run(StudyApplication.class, args);
	}

}

연관관계 매핑

연관관계의 주인

@ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_id")
    private Member member;

양방향 매핑 시, 참조의 대상이 되는 엔티티(주인x)

@OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
    private List<MemberPrefer> memberPreferList = new ArrayList<>();

칼럼 별 세부적인 설정

@Enumerated(EnumType.STRING)
    @Column(columnDefinition = "VARCHAR(15) DEFAULT 'ACTIVE'")
    private MemberStatus status;
profile
백문이 불여일기

0개의 댓글