JPA

김창모·2023년 5월 27일
0

SpringBoot

목록 보기
7/19

JPA 란 ?

Java 진영에서 ORM 기술 표준으로 사용하는 인터페이스 모음으로 자바 애플리케이션 에서 관계형 데이터 베이스 (RDBMS) 를 사용하는 방식을 정의한 인터페이스 이며 인터페이스 이기 때문에 구현체가 필요하다.

ORM 이란 ?

Java 에선 Class 를 사용하고 RDBMS 에선 테이블을 사용한다.
이로인해 객체 모델과 관계형 모델간의 불일치가 존재한다.
DB 에 데이터를 CRUD 하기 위해선 query 를 전송해야 하지만 ORM 을 통해 데이터베이스 설계 중심의 패러다임을 객체 설계 중심으로 으로 역전하여 불일치를 해소해준다.

JPA 의 장점

1. 생산성

SQL을 작성하고 JDBC 코드를 작성하는 반복적인 일을 JPA 가 대신 처리해주며 객체를 사용하여 동작하기 때문에 생산성이 증가한다.

2. 유지보수

Entity 필드에 변경사항이 발생했을때 수정해야할 많은 부분을 감소시켜주어 유지보수성을 향상시켜준다.

3. 패러다임 불일치 해결

SQL 중심이 아니라 Java 객체 중심으로 데이터를 관리할수 있다.

4. 특정 데이터 베이스에 종속적이지 않다.

JPA는 추상화된 데이터 접근 계층을 제공하여 특정 데이터 베이스 문법에 종속적이지 않으며 간단한 설정으로 변경 가능하다.

JPA 의 단점

1. 올바른 설계의 중요성

매핑 설계를 잘못할 경우 성능 저하의 가능성이 존재한다.

2. 학습의 필요성

JPA 를 제대로 사용하기 위해서 학습해야할 내용이 많다.

3. JPA 만으로 처리 불가능한 query

JPA 만으로 모든 쿼리를 처리할수 없는 경우가 발생한다. 필자가 들었던 김영한 님의 강의에선 이를 QueryDsl 과 NativeQuery 를 함께 사용하여 해결한다고 하였다.

Entity

엔티티(Entity) 란 DB 테이블과 매핑되는 클래스이다.

domain/entity 디렉토리를 만들고 Member 클래스를 만들었다.

package com.hello.hello.domain.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Member {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String email;
    private String name;
    private String password;
}

@Entity

이 클래스가 Entity 임을 선언하는 어노테이션이다.

@Getter

Entity Class 의 필드에 접근하기 위한 메서드를 자동적으로 생성해준다.
Ex) getEmail() , getName()

@NoArgsConstructor

Entity Class 의 기본 생성자를 자동으로 생성해준다.
JPA 는 DB 값을 필드에 주입할때 기본 생성자로 객체를 생성한 후 Reflection 을 사용하여 매핑하기 때문이다.

@AllArgsConstructor

전체 변수를 생성하는 생성자를 자동으로 생성해준다.

@Id

각 Entity 들을 구분하기 위한 키값(PK)을 설정해준다.

@GeneratedValue

@Id 어노테이션을 붙인 필드의 PK 생성 전략을 설정할수 있다.

strategy = GenerationType.IDENTITY

PK 생성을 데이터베이스에 위임한다. 예를들어 MySql 에서는 Auto_Increment 를 사용하여 PK 를 생성한다.

권장 Stretegy

sequence table auto 등의 GenerationType 이 존재하지만 권장하는 PK 생성 전략은
1. Long Type
2. 대체키 사용
3. Auto_Increment
이기 때문에 IDENTITY 를 사용하겠다.

Add Controller , Service , Dto

Member Entity 를 만들었으니 MemberController 와 MemberService 를 추가해주겠다.

MemberController

package com.hello.hello.controller;

import com.hello.hello.domain.dto.SignUpDto;
import com.hello.hello.service.MemberService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class MemberController {
    private final MemberService memberService;

    public Long save(@RequestBody SignUpDto signUpDto) {
        return memberService.saveMember(signUpDto);
    }
}

@RequestBody

@RequestBody 어노테이션은 컨트롤러에 요청시 json 데이터를 보낼때 @RequestBody 뒤 객체의 필드값과 일치할경우 Json 값을 자바 객체로 변환시켜 저장한다.

MemberService

package com.hello.hello.service;

import com.hello.hello.domain.dto.SignUpDto;
import com.hello.hello.repository.MemberJpaRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class MemberService {
    private final MemberJpaRepository memberJpaRepository;

    public Long saveMember(SignUpDto signUpDto) {
        return 0L;
    }
}

SignUpDto

package com.hello.hello.domain.dto;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class SignUpDto {
    private String email;
    private String name;
    private String password;

    @Builder
    public SignUpDto(String email, String name, String password) {
        this.email = email;
        this.name = name;
        this.password = password;
    }
}

@Builder

SignUpDto 의 생성자를 보면 @Builder 어노테이션이 붙어있다.
@Builder 어노테이션은
1. 필요한 데이터만 설정가능
2. 유연성 확보
3. 가독성
4. 변경 가능성의 최소화
위의 이유로 권장되는 패턴이다.

0개의 댓글